Index: src/eog-scroll-view.c
===================================================================
--- src/eog-scroll-view.c	(revisión: 4685)
+++ src/eog-scroll-view.c	(copia de trabajo)
@@ -1,3 +1,28 @@
+/* Eye of GNOME -- Image Viewing Widget
+ *
+ * Copyright (C) 2008 The Free Software Foundation
+ *
+ * Author: Javier Sanchez  <jsanchez@deskblue.com>
+ *
+ * Based on code by:
+ *      - Lucas Rocha       <lucasr@gnome.org>
+ * 	- Claudio Saavedra  <csaavedra@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -2,1902 +27,37 @@
 
-#include <math.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "eog-marshal.h"
 #include "eog-scroll-view.h"
-#include "eog-debug.h"
-#include "uta.h"
-#include "zoom.h"
 
-/* Maximum size of delayed repaint rectangles */
-#define PAINT_RECT_WIDTH 128
-#define PAINT_RECT_HEIGHT 128
-
-/* Scroll step increment */
-#define SCROLL_STEP_SIZE 32
-
-/* Maximum zoom factor */
-#define MAX_ZOOM_FACTOR 20
-#define MIN_ZOOM_FACTOR 0.02
-
-#define CHECK_MEDIUM 8
-#define CHECK_BLACK 0x00000000
-#define CHECK_DARK 0x00555555
-#define CHECK_GRAY 0x00808080
-#define CHECK_LIGHT 0x00cccccc
-#define CHECK_WHITE 0x00ffffff
-
-/* Default increment for zooming.  The current zoom factor is multiplied or
- * divided by this amount on every zooming step.  For consistency, you should
- * use the same value elsewhere in the program.
- */
-#define IMAGE_VIEW_ZOOM_MULTIPLIER 1.05
-
-/* States for automatically adjusting the zoom factor */
-typedef enum {
-	ZOOM_MODE_FIT,		/* Image is fitted to scroll view even if the latter changes size */
-	ZOOM_MODE_FREE		/* The image remains at its current zoom factor even if the scrollview changes size  */
-} ZoomMode;
-
-/* Progressive loading state */
-typedef enum {
-	PROGRESSIVE_NONE,	/* We are not loading an image or it is already loaded */
-	PROGRESSIVE_LOADING,	/* An image is being loaded */
-	PROGRESSIVE_POLISHING	/* We have finished loading an image but have not scaled it with interpolation */
-} ProgressiveState;
-
-/* Signal IDs */
-enum {
-	SIGNAL_ZOOM_CHANGED,
-	SIGNAL_LAST
-};
-static gint view_signals [SIGNAL_LAST];
-
-typedef enum {
-	EOG_SCROLL_VIEW_CURSOR_NORMAL,
-	EOG_SCROLL_VIEW_CURSOR_HIDDEN,
-	EOG_SCROLL_VIEW_CURSOR_DRAG
-} EogScrollViewCursor;
-
-/* Private part of the EogScrollView structure */
+/* --- Private part of the EogScrollView structure --- */
 struct _EogScrollViewPrivate {
-	/* some widgets we rely on */
-	GtkWidget *display;
-	GtkAdjustment *hadj;
-	GtkAdjustment *vadj;
-	GtkWidget *hbar;
-	GtkWidget *vbar;
-	GtkWidget *menu;
-
-	/* actual image */
-	EogImage *image;
-	guint image_changed_id;
-	GdkPixbuf *pixbuf;
-
-	/* zoom mode, either ZOOM_MODE_FIT or ZOOM_MODE_FREE */
-	ZoomMode zoom_mode;
-
-	/* whether to allow zoom > 1.0 on zoom fit */
-	gboolean upscale;
-
-	/* the actual zoom factor */
-	double zoom;
-
-	/* the minimum possible (reasonable) zoom factor */
-	double min_zoom;
-
-	/* Current scrolling offsets */
-	int xofs, yofs;
-
-	/* Microtile arrays for dirty region.  This represents the dirty region
-	 * for interpolated drawing.
-	 */
-	ArtUta *uta;
-
-	/* handler ID for paint idle callback */
-	guint idle_id;
-
-	/* Interpolation type */
-	GdkInterpType interp_type;
-
-	/* Scroll wheel zoom */
-	gboolean scroll_wheel_zoom;
-
-	/* Scroll wheel zoom */
-	gdouble zoom_multiplier;
-
-	/* dragging stuff */
-	int drag_anchor_x, drag_anchor_y;
-	int drag_ofs_x, drag_ofs_y;
-	guint dragging : 1;
-
-	/* status of progressive loading */
-	ProgressiveState progressive_state;
-
-	/* how to indicate transparency in images */
-	EogTransparencyStyle transp_style;
-	guint32 transp_color;
-
-	/* the type of the cursor we are currently showing */
-	EogScrollViewCursor cursor;
 };
 
-static void scroll_by (EogScrollView *view, int xofs, int yofs);
-static void set_zoom_fit (EogScrollView *view);
-static void request_paint_area (EogScrollView *view, GdkRectangle *area);
-static void set_minimum_zoom_factor (EogScrollView *view);
-
 #define EOG_SCROLL_VIEW_GET_PRIVATE(object) \
 	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_SCROLL_VIEW, EogScrollViewPrivate))
 
-G_DEFINE_TYPE (EogScrollView, eog_scroll_view, GTK_TYPE_TABLE)
+G_DEFINE_TYPE (EogScrollView, eog_scroll_view, EOG_TYPE_VIEW)
 
-
-/*===================================
-    widget size changing handler &
-        util functions
-  ---------------------------------*/
+/* --- Object creation --- */
+static void eog_scroll_view_class_init (EogScrollViewClass *klass);
+static void eog_scroll_view_init       (EogScrollView *view);
+static void eog_scroll_view_finalize   (GObject *object);
 
-/* Disconnects from the EogImage and removes references to it */
-static void
-free_image_resources (EogScrollView *view)
-{
-	EogScrollViewPrivate *priv;
+GtkWidget  *eog_scroll_view_new        (void);
 
-	priv = view->priv;
 
-	if (priv->image_changed_id > 0) {
-		g_signal_handler_disconnect (G_OBJECT (priv->image), priv->image_changed_id);
-		priv->image_changed_id = 0;
-	}
-
-	if (priv->image != NULL) {
-		eog_image_data_unref (priv->image);
-		priv->image = NULL;
-	}
-
-	if (priv->pixbuf != NULL) {
-		g_object_unref (priv->pixbuf);
-		priv->pixbuf = NULL;
-	}
-}
-
-/* Computes the size in pixels of the scaled image */
+/* --- Object creation --- */
 static void
-compute_scaled_size (EogScrollView *view, double zoom, int *width, int *height)
+eog_scroll_view_class_init (EogScrollViewClass *klass)
 {
-	EogScrollViewPrivate *priv;
+	GObjectClass *gobject_class;
+	GtkWidgetClass *widget_class;
 
-	priv = view->priv;
+	gobject_class = (GObjectClass*) klass;
+	widget_class = (GtkWidgetClass*) klass;
 
-	if (priv->pixbuf) {
-		*width = floor (gdk_pixbuf_get_width (priv->pixbuf) * zoom + 0.5);
-		*height = floor (gdk_pixbuf_get_height (priv->pixbuf) * zoom + 0.5);
-	} else
-		*width = *height = 0;
-}
+	gobject_class->finalize = eog_scroll_view_finalize;
 
-/* Computes the offsets for the new zoom value so that they keep the image
- * centered on the view.
- */
-static void
-compute_center_zoom_offsets (EogScrollView *view,
-			     double old_zoom, double new_zoom,
-			     int width, int height,
-			     double zoom_x_anchor, double zoom_y_anchor,
-			     int *xofs, int *yofs)
-{
-	EogScrollViewPrivate *priv;
-	int old_scaled_width, old_scaled_height;
-	int new_scaled_width, new_scaled_height;
-	double view_cx, view_cy;
-
-	priv = view->priv;
-
-	compute_scaled_size (view, old_zoom,
-			     &old_scaled_width, &old_scaled_height);
-
-	if (old_scaled_width < width)
-		view_cx = (zoom_x_anchor * old_scaled_width) / old_zoom;
-	else
-		view_cx = (priv->xofs + zoom_x_anchor * width) / old_zoom;
-
-	if (old_scaled_height < height)
-		view_cy = (zoom_y_anchor * old_scaled_height) / old_zoom;
-	else
-		view_cy = (priv->yofs + zoom_y_anchor * height) / old_zoom;
-
-	compute_scaled_size (view, new_zoom,
-			     &new_scaled_width, &new_scaled_height);
-
-	if (new_scaled_width < width)
-		*xofs = 0;
-	else {
-		*xofs = floor (view_cx * new_zoom - zoom_x_anchor * width + 0.5);
-		if (*xofs < 0)
-			*xofs = 0;
-	}
-
-	if (new_scaled_height < height)
-		*yofs = 0;
-	else {
-		*yofs = floor (view_cy * new_zoom - zoom_y_anchor * height + 0.5);
-		if (*yofs < 0)
-			*yofs = 0;
-	}
+	g_type_class_add_private (klass, sizeof (EogScrollViewPrivate));
 }
 
-/* Sets the scrollbar values based on the current scrolling offset */
 static void
-update_scrollbar_values (EogScrollView *view)
-{
-	EogScrollViewPrivate *priv;
-	int scaled_width, scaled_height;
-	int xofs, yofs;
-	GtkAllocation *allocation;
-
-	priv = view->priv;
-
-	if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->hbar)) && !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->vbar)))
-		return;
-
-	compute_scaled_size (view, priv->zoom, &scaled_width, &scaled_height);
-	allocation = &GTK_WIDGET (priv->display)->allocation;
-
-	if (GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->hbar))) {
-		/* Set scroll increments */
-		priv->hadj->page_size = MIN (scaled_width, allocation->width);
-		priv->hadj->page_increment = allocation->width / 2;
-		priv->hadj->step_increment = SCROLL_STEP_SIZE;
-
-		/* Set scroll bounds and new offsets */
-		priv->hadj->lower = 0;
-		priv->hadj->upper = scaled_width;
-		xofs = CLAMP (priv->xofs, 0, priv->hadj->upper - priv->hadj->page_size);
-		if (priv->hadj->value != xofs) {
-			priv->hadj->value = xofs;
-			priv->xofs = xofs;
-
-			g_signal_handlers_block_matched (
-				priv->hadj, G_SIGNAL_MATCH_DATA,
-				0, 0, NULL, NULL, view);
-
-			gtk_adjustment_changed (priv->hadj);
-
-			g_signal_handlers_unblock_matched (
-				priv->hadj, G_SIGNAL_MATCH_DATA,
-				0, 0, NULL, NULL, view);
-		}
-	}
-
-	if (GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->vbar))) {
-		priv->vadj->page_size = MIN (scaled_height, allocation->height);
-		priv->vadj->page_increment = allocation->height / 2;
-		priv->vadj->step_increment = SCROLL_STEP_SIZE;
-
-		priv->vadj->lower = 0;
-		priv->vadj->upper = scaled_height;
-		yofs = CLAMP (priv->yofs, 0, priv->vadj->upper - priv->vadj->page_size);
-
-		if (priv->vadj->value != yofs) {
-			priv->vadj->value = yofs;
-			priv->yofs = yofs;
-
-			g_signal_handlers_block_matched (
-				priv->vadj, G_SIGNAL_MATCH_DATA,
-				0, 0, NULL, NULL, view);
-
-			gtk_adjustment_changed (priv->vadj);
-
-			g_signal_handlers_unblock_matched (
-				priv->vadj, G_SIGNAL_MATCH_DATA,
-				0, 0, NULL, NULL, view);
-		}
-	}
-}
-
-static GdkCursor *
-eog_scroll_view_create_invisible_cursor (void)
-{
-       GdkBitmap *empty;
-       GdkColor black = { 0, 0, 0, 0 };
-       static char bits[] = { 0x00 };
-
-       empty = gdk_bitmap_create_from_data (NULL, bits, 1, 1);
-
-       return gdk_cursor_new_from_pixmap (empty, empty, &black, &black, 0, 0);
-}
-
-static void
-eog_scroll_view_set_cursor (EogScrollView *view, EogScrollViewCursor new_cursor)
-{
-	GdkCursor *cursor = NULL;
-	GdkDisplay *display;
-	GtkWidget *widget;
-
-	if (view->priv->cursor == new_cursor) {
-		return;
-	}
-
-	widget = gtk_widget_get_toplevel (GTK_WIDGET (view));
-	display = gtk_widget_get_display (widget);
-	view->priv->cursor = new_cursor;
-
-	switch (new_cursor) {
-		case EOG_SCROLL_VIEW_CURSOR_NORMAL:
-			gdk_window_set_cursor (widget->window, NULL);
-			break;
-                case EOG_SCROLL_VIEW_CURSOR_HIDDEN:
-                        cursor = eog_scroll_view_create_invisible_cursor ();
-                        break;
-		case EOG_SCROLL_VIEW_CURSOR_DRAG:
-			cursor = gdk_cursor_new_for_display (display, GDK_FLEUR);
-			break;
-	}
-
-	if (cursor) {
-		gdk_window_set_cursor (widget->window, cursor);
-		gdk_cursor_unref (cursor);
-		gdk_flush();
-	}
-}
-
-/* Changes visibility of the scrollbars based on the zoom factor and the
- * specified allocation, or the current allocation if NULL is specified.
- */
-static void
-check_scrollbar_visibility (EogScrollView *view, GtkAllocation *alloc)
-{
-	EogScrollViewPrivate *priv;
-	int bar_height;
-	int bar_width;
-	int img_width;
-	int img_height;
-	GtkRequisition req;
-	int width, height;
-	gboolean hbar_visible, vbar_visible;
-
-	priv = view->priv;
-
-	if (alloc) {
-		width = alloc->width;
-		height = alloc->height;
-	} else {
-		width = GTK_WIDGET (view)->allocation.width;
-		height = GTK_WIDGET (view)->allocation.height;
-	}
-
-	compute_scaled_size (view, priv->zoom, &img_width, &img_height);
-
-	/* this should work fairly well in this special case for scrollbars */
-	gtk_widget_size_request (priv->hbar, &req);
-	bar_height = req.height;
-	gtk_widget_size_request (priv->vbar, &req);
-	bar_width = req.width;
-
-	eog_debug_message (DEBUG_WINDOW, "Widget Size allocate: %i, %i   Bar: %i, %i\n", 
-			   width, height, bar_width, bar_height);
-
-	hbar_visible = vbar_visible = FALSE;
-	if (priv->zoom_mode == ZOOM_MODE_FIT)
-		hbar_visible = vbar_visible = FALSE;
-	else if (img_width <= width && img_height <= height)
-		hbar_visible = vbar_visible = FALSE;
-	else if (img_width > width && img_height > height)
-		hbar_visible = vbar_visible = TRUE;
-	else if (img_width > width) {
-		hbar_visible = TRUE;
-		if (img_height <= (height - bar_height))
-			vbar_visible = FALSE;
-		else
-			vbar_visible = TRUE;
-	}
-        else if (img_height > height) {
-		vbar_visible = TRUE;
-		if (img_width <= (width - bar_width))
-			hbar_visible = FALSE;
-		else
-			hbar_visible = TRUE;
-	}
-
-	if (hbar_visible != GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->hbar)))
-		g_object_set (G_OBJECT (priv->hbar), "visible", hbar_visible, NULL);
-
-	if (vbar_visible != GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->vbar)))
-		g_object_set (G_OBJECT (priv->vbar), "visible", vbar_visible, NULL);
-}
-
-#define DOUBLE_EQUAL_MAX_DIFF 1e-6
-#define DOUBLE_EQUAL(a,b) (fabs (a - b) < DOUBLE_EQUAL_MAX_DIFF)
-
-/* Returns whether the zoom factor is 1.0 */
-static gboolean
-is_unity_zoom (EogScrollView *view)
-{
-	EogScrollViewPrivate *priv;
-
-	priv = view->priv;
-	return DOUBLE_EQUAL (priv->zoom, 1.0);
-}
-
-/* Returns wether the image is movable, that means if it is larger then 
- * the actual visible area.
- */
-static gboolean
-is_image_movable (EogScrollView *view)
-{
-	EogScrollViewPrivate *priv;
-
-	priv = view->priv;
-
-	return (GTK_WIDGET_VISIBLE (priv->hbar) || GTK_WIDGET_VISIBLE (priv->vbar));
-}
-
-
-/* Computes the image offsets with respect to the window */
-/*
-static void
-get_image_offsets (EogScrollView *view, int *xofs, int *yofs)
-{
-	EogScrollViewPrivate *priv;
-	int scaled_width, scaled_height;
-	int width, height;
-
-	priv = view->priv;
-
-	compute_scaled_size (view, priv->zoom, &scaled_width, &scaled_height);
-
-	width = GTK_WIDGET (priv->display)->allocation.width;
-	height = GTK_WIDGET (priv->display)->allocation.height;
-
-	// Compute image offsets with respect to the window
-	if (scaled_width <= width)
-		*xofs = (width - scaled_width) / 2;
-	else
-		*xofs = -priv->xofs;
-
-	if (scaled_height <= height)
-		*yofs = (height - scaled_height) / 2;
-	else
-		*yofs = -priv->yofs;
-}
-*/
-
-/*===================================
-          drawing core
-  ---------------------------------*/
-
-
-/* Pulls a rectangle from the specified microtile array.  The rectangle is the
- * first one that would be glommed together by art_rect_list_from_uta(), and its
- * size is bounded by max_width and max_height.  The rectangle is also removed
- * from the microtile array.
- */
-static void
-pull_rectangle (ArtUta *uta, ArtIRect *rect, int max_width, int max_height)
-{
-	uta_find_first_glom_rect (uta, rect, max_width, max_height);
-	uta_remove_rect (uta, rect->x0, rect->y0, rect->x1, rect->y1);
-}
-
-/* Paints a rectangle with the background color if the specified rectangle
- * intersects the dirty rectangle.
- */
-static void
-paint_background (EogScrollView *view, ArtIRect *r, ArtIRect *rect)
-{
-	EogScrollViewPrivate *priv;
-	ArtIRect d;
-
-	priv = view->priv;
-
-	art_irect_intersect (&d, r, rect);
-	if (!art_irect_empty (&d)) {
-		gdk_window_clear_area (GTK_WIDGET (priv->display)->window,
-				       d.x0, d.y0,
-				       d.x1 - d.x0, d.y1 - d.y0);
-	}
-}
-
-/* Paints a rectangle of the dirty region */
-static void
-paint_rectangle (EogScrollView *view, ArtIRect *rect, GdkInterpType interp_type)
-{
-	EogScrollViewPrivate *priv;
-	int scaled_width, scaled_height;
-	int width, height;
-	int xofs, yofs;
-	ArtIRect r, d;
-	GdkPixbuf *tmp;
-	int check_size;
-	char *str;
-	guint32 check_1 = 0;
-	guint32 check_2 = 0;
-
-	priv = view->priv;
-
-	if (!GTK_WIDGET_DRAWABLE (priv->display))
-		return;
-
-	compute_scaled_size (view, priv->zoom, &scaled_width, &scaled_height);
-
-	width = GTK_WIDGET (priv->display)->allocation.width;
-	height = GTK_WIDGET (priv->display)->allocation.height;
-
-	if (scaled_width < 1 || scaled_height < 1)
-	{
-		r.x0 = 0;
-		r.y0 = 0;
-		r.x1 = width;
-		r.y1 = height;
-		paint_background (view, &r, rect);
-		return;
-	}
-	
-	/* Compute image offsets with respect to the window */
-
-	if (scaled_width <= width)
-		xofs = (width - scaled_width) / 2;
-	else
-		xofs = -priv->xofs;
-
-	if (scaled_height <= height)
-		yofs = (height - scaled_height) / 2;
-	else
-		yofs = -priv->yofs;
-
-	eog_debug_message (DEBUG_WINDOW, "zoom %.2f, xofs: %i, yofs: %i scaled w: %i h: %i\n", 
-			   priv->zoom, xofs, yofs, scaled_width, scaled_height);
-
-	/* Draw background if necessary, in four steps */
-
-	/* Top */
-	if (yofs > 0) {
-		r.x0 = 0;
-		r.y0 = 0;
-		r.x1 = width;
-		r.y1 = yofs;
-		paint_background (view, &r, rect);
-	}
-
-	/* Left */
-	if (xofs > 0) {
-		r.x0 = 0;
-		r.y0 = yofs;
-		r.x1 = xofs;
-		r.y1 = yofs + scaled_height;
-		paint_background (view, &r, rect);
-	}
-
-	/* Right */
-	if (xofs >= 0) {
-		r.x0 = xofs + scaled_width;
-		r.y0 = yofs;
-		r.x1 = width;
-		r.y1 = yofs + scaled_height;
-		if (r.x0 < r.x1)
-			paint_background (view, &r, rect);
-	}
-
-	/* Bottom */
-	if (yofs >= 0) {
-		r.x0 = 0;
-		r.y0 = yofs + scaled_height;
-		r.x1 = width;
-		r.y1 = height;
-		if (r.y0 < r.y1)
-			paint_background (view, &r, rect);
-	}
-
-
-	/* Draw the scaled image
-	 *
-	 * FIXME: this is not using the color correction tables!
-	 */
-
-	if (!priv->pixbuf)
-		return;
-
-	r.x0 = xofs;
-	r.y0 = yofs;
-	r.x1 = xofs + scaled_width;
-	r.y1 = yofs + scaled_height;
-
-	art_irect_intersect (&d, &r, rect);
-	if (art_irect_empty (&d))
-		return;
-
-	switch (interp_type) {
-	case GDK_INTERP_NEAREST:
-		str = "NEAREST";
-		break;
-	default:
-		str = "ALIASED";
-	}
-
-	eog_debug_message (DEBUG_WINDOW, "%s: x0: %i,\t y0: %i,\t x1: %i,\t y1: %i\n", 
-			   str, d.x0, d.y0, d.x1, d.y1);
-
-	/* Short-circuit the fast case to avoid a memcpy() */
-
-	if (is_unity_zoom (view)
-	    && gdk_pixbuf_get_colorspace (priv->pixbuf) == GDK_COLORSPACE_RGB
-	    && !gdk_pixbuf_get_has_alpha (priv->pixbuf)
-	    && gdk_pixbuf_get_bits_per_sample (priv->pixbuf) == 8) {
-		guchar *pixels;
-		int rowstride;
-
-		rowstride = gdk_pixbuf_get_rowstride (priv->pixbuf);
-
-		pixels = (gdk_pixbuf_get_pixels (priv->pixbuf)
-			  + (d.y0 - yofs) * rowstride
-			  + 3 * (d.x0 - xofs));
-
-		gdk_draw_rgb_image_dithalign (GTK_WIDGET (priv->display)->window,
-					      GTK_WIDGET (priv->display)->style->black_gc,
-					      d.x0, d.y0,
-					      d.x1 - d.x0, d.y1 - d.y0,
-					      GDK_RGB_DITHER_MAX,
-					      pixels,
-					      rowstride,
-					      d.x0 - xofs, d.y0 - yofs);
-		return;
-	}
-
-	/* For all other cases, create a temporary pixbuf */
-
-	tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, d.x1 - d.x0, d.y1 - d.y0);
-
-	if (!tmp) {
-		g_message ("paint_rectangle(): Could not allocate temporary pixbuf of "
-			   "size (%d, %d); skipping", d.x1 - d.x0, d.y1 - d.y0);
-		return;
-	}
-
-	/* Compute transparency parameters */
-	switch (priv->transp_style) {
-	case EOG_TRANSP_BACKGROUND: {
-		GdkColor color = GTK_WIDGET (priv->display)->style->bg[GTK_STATE_NORMAL];
-
-		check_1 = check_2 = (((color.red & 0xff00) << 8)
-				     | (color.green & 0xff00)
-				     | ((color.blue & 0xff00) >> 8));
-		break; }
-
-	case EOG_TRANSP_CHECKED:
-		check_1 = CHECK_GRAY;
-		check_2 = CHECK_LIGHT;
-		break;
-
-	case EOG_TRANSP_COLOR:
-		check_1 = check_2 = priv->transp_color;
-		break;
-
-	default:
-		g_assert_not_reached ();
-	};
-
-	check_size = CHECK_MEDIUM;
-
-	/* Draw! */
-	gdk_pixbuf_composite_color (priv->pixbuf,
-				    tmp,
-				    0, 0,
-				    d.x1 - d.x0, d.y1 - d.y0,
-				    -(d.x0 - xofs), -(d.y0 - yofs),
-				    priv->zoom, priv->zoom,
-				    is_unity_zoom (view) ? GDK_INTERP_NEAREST : interp_type,
-				    255,
-				    d.x0 - xofs, d.y0 - yofs,
-				    check_size,
-				    check_1, check_2);
-
-	gdk_draw_rgb_image_dithalign (GTK_WIDGET (priv->display)->window,
-				      GTK_WIDGET (priv->display)->style->black_gc,
-				      d.x0, d.y0,
-				      d.x1 - d.x0, d.y1 - d.y0,
-				      GDK_RGB_DITHER_MAX,
-				      gdk_pixbuf_get_pixels (tmp),
-				      gdk_pixbuf_get_rowstride (tmp),
-				      d.x0 - xofs, d.y0 - yofs);
-
-	g_object_unref (tmp);
-}
-
-
-/* Idle handler for the drawing process.  We pull a rectangle from the dirty
- * region microtile array, paint it, and leave the rest to the next idle
- * iteration.
- */
-static gboolean
-paint_iteration_idle (gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-	ArtIRect rect;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	g_assert (priv->uta != NULL);
-
-	pull_rectangle (priv->uta, &rect, PAINT_RECT_WIDTH, PAINT_RECT_HEIGHT);
-
-	if (art_irect_empty (&rect)) {
-		art_uta_free (priv->uta);
-		priv->uta = NULL;
-	} else
-		paint_rectangle (view, &rect, priv->interp_type);
-
-	if (!priv->uta) {
-		priv->idle_id = 0;
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/* Paints the requested area in non-interpolated mode.  Then, if we are
- * configured to use interpolation, we queue an idle handler to redraw the area
- * with interpolation.  The area is in window coordinates.
- */
-static void
-request_paint_area (EogScrollView *view, GdkRectangle *area)
-{
-	EogScrollViewPrivate *priv;
-	ArtIRect r;
-
-	priv = view->priv;
-
-	eog_debug_message (DEBUG_WINDOW, "x: %i, y: %i, width: %i, height: %i\n", 
-			   area->x, area->y, area->width, area->height);
-
-	if (!GTK_WIDGET_DRAWABLE (priv->display))
-		return;
-
-	r.x0 = MAX (0, area->x);
-	r.y0 = MAX (0, area->y);
-	r.x1 = MIN (GTK_WIDGET (priv->display)->allocation.width, area->x + area->width);
-	r.y1 = MIN (GTK_WIDGET (priv->display)->allocation.height, area->y + area->height);
-
-	eog_debug_message (DEBUG_WINDOW, "r: %i, %i, %i, %i\n", r.x0, r.y0, r.x1, r.y1);
-
-	if (r.x0 >= r.x1 || r.y0 >= r.y1)
-		return;
-
-	/* Do nearest neighbor, 1:1 zoom or active progressive loading synchronously for speed.  */
-	if (priv->interp_type == GDK_INTERP_NEAREST ||
-	    is_unity_zoom (view) ||
-	    priv->progressive_state == PROGRESSIVE_LOADING) {
-		paint_rectangle (view, &r, GDK_INTERP_NEAREST);
-		return;
-	}
-
-	if (priv->progressive_state == PROGRESSIVE_POLISHING)
-		/* We have already a complete image with nearest neighbor mode.
-		 * It's sufficient to add only a antitaliased idle update
-		 */
-		priv->progressive_state = PROGRESSIVE_NONE;
-	else
-		/* do nearest neigbor before anti aliased version */
-		paint_rectangle (view, &r, GDK_INTERP_NEAREST);
-
-	/* All other interpolation types are delayed.  */
-	if (priv->uta)
-		g_assert (priv->idle_id != 0);
-	else {
-		g_assert (priv->idle_id == 0);
-		priv->idle_id = g_idle_add (paint_iteration_idle, view);
-	}
-
-	priv->uta = uta_add_rect (priv->uta, r.x0, r.y0, r.x1, r.y1);
-}
-
-
-/* =======================================
-
-    scrolling stuff
-
-    --------------------------------------*/
-
-
-/* Scrolls the view to the specified offsets.  */
-static void
-scroll_to (EogScrollView *view, int x, int y, gboolean change_adjustments)
-{
-	EogScrollViewPrivate *priv;
-	int xofs, yofs;
-	GdkWindow *window;
-	int width, height;
-	int src_x, src_y;
-	int dest_x, dest_y;
-	int twidth, theight;
-
-	priv = view->priv;
-
-	/* Check bounds & Compute offsets */
-	if (GTK_WIDGET_VISIBLE (priv->hbar)) {
-		x = CLAMP (x, 0, priv->hadj->upper - priv->hadj->page_size);
-		xofs = x - priv->xofs;
-	} else
-		xofs = 0;
-
-	if (GTK_WIDGET_VISIBLE (priv->vbar)) {
-		y = CLAMP (y, 0, priv->vadj->upper - priv->vadj->page_size);
-		yofs = y - priv->yofs;
-	} else
-		yofs = 0;
-
-	if (xofs == 0 && yofs == 0)
-		return;
-
-	priv->xofs = x;
-	priv->yofs = y;
-
-	if (!GTK_WIDGET_DRAWABLE (priv->display))
-		goto out;
-
-	width = GTK_WIDGET (priv->display)->allocation.width;
-	height = GTK_WIDGET (priv->display)->allocation.height;
-
-	if (abs (xofs) >= width || abs (yofs) >= height) {
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-		goto out;
-	}
-
-	window = GTK_WIDGET (priv->display)->window;
-
-	/* Ensure that the uta has the full size */
-
-	twidth = (width + ART_UTILE_SIZE - 1) >> ART_UTILE_SHIFT;
-	theight = (height + ART_UTILE_SIZE - 1) >> ART_UTILE_SHIFT;
-
-	if (priv->uta)
-		g_assert (priv->idle_id != 0);
-	else
-		priv->idle_id = g_idle_add (paint_iteration_idle, view);
-
-	priv->uta = uta_ensure_size (priv->uta, 0, 0, twidth, theight);
-
-	/* Copy the uta area.  Our synchronous handling of expose events, below,
-	 * will queue the new scrolled-in areas.
-	 */
-	src_x = xofs < 0 ? 0 : xofs;
-	src_y = yofs < 0 ? 0 : yofs;
-	dest_x = xofs < 0 ? -xofs : 0;
-	dest_y = yofs < 0 ? -yofs : 0;
-
-	uta_copy_area (priv->uta,
-		       src_x, src_y,
-		       dest_x, dest_y,
-		       width - abs (xofs), height - abs (yofs));
-
-	/* Scroll the window area and process exposure synchronously. */
-
-	gdk_window_scroll (window, -xofs, -yofs);
-	gdk_window_process_updates (window, TRUE);
-
- out:
-	if (!change_adjustments)
-		return;
-
-	g_signal_handlers_block_matched (
-		priv->hadj, G_SIGNAL_MATCH_DATA,
-		0, 0, NULL, NULL, view);
-	g_signal_handlers_block_matched (
-		priv->vadj, G_SIGNAL_MATCH_DATA,
-		0, 0, NULL, NULL, view);
-
-	priv->hadj->value = x;
-	priv->vadj->value = y;
-
-	gtk_adjustment_value_changed (priv->hadj);
-	gtk_adjustment_value_changed (priv->vadj);
-
-	g_signal_handlers_unblock_matched (
-		priv->hadj, G_SIGNAL_MATCH_DATA,
-		0, 0, NULL, NULL, view);
-	g_signal_handlers_unblock_matched (
-		priv->vadj, G_SIGNAL_MATCH_DATA,
-		0, 0, NULL, NULL, view);
-}
-
-/* Scrolls the image view by the specified offsets.  Notifies the adjustments
- * about their new values.
- */
-static void
-scroll_by (EogScrollView *view, int xofs, int yofs)
-{
-	EogScrollViewPrivate *priv;
-
-	priv = view->priv;
-
-	scroll_to (view, priv->xofs + xofs, priv->yofs + yofs, TRUE);
-}
-
-
-/* Callback used when an adjustment is changed */
-static void
-adjustment_changed_cb (GtkAdjustment *adj, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	scroll_to (view, priv->hadj->value, priv->vadj->value, FALSE);
-}
-
-
-/* Drags the image to the specified position */
-static void
-drag_to (EogScrollView *view, int x, int y)
-{
-	EogScrollViewPrivate *priv;
-	int dx, dy;
-
-	priv = view->priv;
-
-	dx = priv->drag_anchor_x - x;
-	dy = priv->drag_anchor_y - y;
-
-	x = priv->drag_ofs_x + dx;
-	y = priv->drag_ofs_y + dy;
-
-	scroll_to (view, x, y, TRUE);
-}
-
-static void
-set_minimum_zoom_factor (EogScrollView *view)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-	
-	view->priv->min_zoom = MAX (1.0 / gdk_pixbuf_get_width (view->priv->pixbuf),
-				    MAX(1.0 / gdk_pixbuf_get_height (view->priv->pixbuf),
-					MIN_ZOOM_FACTOR) );
-	return;
-}
-
-/**
- * set_zoom:
- * @view: A scroll view.
- * @zoom: Zoom factor.
- * @have_anchor: Whether the anchor point specified by (@anchorx, @anchory)
- * should be used.
- * @anchorx: Horizontal anchor point in pixels.
- * @anchory: Vertical anchor point in pixels.
- *
- * Sets the zoom factor for an image view.  The anchor point can be used to
- * specify the point that stays fixed when the image is zoomed.  If @have_anchor
- * is %TRUE, then (@anchorx, @anchory) specify the point relative to the image
- * view widget's allocation that will stay fixed when zooming.  If @have_anchor
- * is %FALSE, then the center point of the image view will be used.
- **/
-static void
-set_zoom (EogScrollView *view, double zoom,
-	  gboolean have_anchor, int anchorx, int anchory)
-{
-	EogScrollViewPrivate *priv;
-	int xofs, yofs;
-	int disp_width, disp_height;
-	double x_rel, y_rel;
-
-	g_assert (zoom > 0.0);
-
-	priv = view->priv;
-
-	if (priv->pixbuf == NULL)
-		return;
-
-	if (zoom > MAX_ZOOM_FACTOR)
-		zoom = MAX_ZOOM_FACTOR;
-	else if (zoom < MIN_ZOOM_FACTOR)
-		zoom = MIN_ZOOM_FACTOR;
-
-	if (DOUBLE_EQUAL (priv->zoom, zoom))
-		return;
-	if (DOUBLE_EQUAL (priv->zoom, priv->min_zoom) && zoom < priv->zoom)
-		return;
-
-	priv->zoom_mode = ZOOM_MODE_FREE;
-
-	disp_width = GTK_WIDGET (priv->display)->allocation.width;
-	disp_height = GTK_WIDGET (priv->display)->allocation.height;
-
-	/* compute new xofs/yofs values */
-	if (have_anchor) {
-		x_rel = (double) anchorx / disp_width;
-		y_rel = (double) anchory / disp_height;
-	} else {
-		x_rel = 0.5;
-		y_rel = 0.5;
-	}
-
-	compute_center_zoom_offsets (view, priv->zoom, zoom,
-				     disp_width, disp_height,
-				     x_rel, y_rel,
-				     &xofs, &yofs);
-
-	/* set new values */
-	priv->xofs = xofs; /* (img_width * x_rel * zoom) - anchorx; */
-	priv->yofs = yofs; /* (img_height * y_rel * zoom) - anchory; */
-#if 0
-	g_print ("xofs: %i  yofs: %i\n", priv->xofs, priv->yofs);
-#endif
-	if (zoom <= priv->min_zoom)
-		priv->zoom = priv->min_zoom;
-	else
-		priv->zoom = zoom;
-
-	/* we make use of the new values here */
-	check_scrollbar_visibility (view, NULL);
-	update_scrollbar_values (view);
-
-	/* repaint the whole image */
-	gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-
-	g_signal_emit (view, view_signals [SIGNAL_ZOOM_CHANGED], 0, priv->zoom);
-}
-
-/* Zooms the image to fit the available allocation */
-static void
-set_zoom_fit (EogScrollView *view)
-{
-	EogScrollViewPrivate *priv;
-	double new_zoom;
-	int width, height;
-
-	priv = view->priv;
-
-	priv->zoom_mode = ZOOM_MODE_FIT;
-
-	if (!GTK_WIDGET_MAPPED (GTK_WIDGET (view)))
-		return;
-
-	if (priv->pixbuf == NULL)
-		return;
-
-	width = GTK_WIDGET (priv->display)->allocation.width;
-	height = GTK_WIDGET (priv->display)->allocation.height;
-
-	new_zoom = zoom_fit_scale (width, height,
-				   gdk_pixbuf_get_width (priv->pixbuf),
-				   gdk_pixbuf_get_height (priv->pixbuf),
-				   priv->upscale);
-
-	if (new_zoom > MAX_ZOOM_FACTOR)
-		new_zoom = MAX_ZOOM_FACTOR;
-	else if (new_zoom < MIN_ZOOM_FACTOR)
-		new_zoom = MIN_ZOOM_FACTOR;
-
-	priv->zoom = new_zoom;
-	priv->xofs = 0;
-	priv->yofs = 0;
-
-	g_signal_emit (view, view_signals [SIGNAL_ZOOM_CHANGED], 0, priv->zoom);
-}
-
-/*===================================
-
-   internal signal callbacks
-
-  ---------------------------------*/
-
-/* Key press event handler for the image view */
-static gboolean
-display_key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-	gboolean do_zoom;
-	double zoom;
-	gboolean do_scroll;
-	int xofs, yofs;
-	int width, height;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	do_zoom = FALSE;
-	do_scroll = FALSE;
-	xofs = yofs = 0;
-	zoom = 1.0;
-
-	width = GTK_WIDGET (priv->display)->allocation.width;
-	height = GTK_WIDGET (priv->display)->allocation.height;
-
-	switch (event->keyval) {
-	case GDK_Up:
-		do_scroll = TRUE;
-		xofs = 0;
-		yofs = -SCROLL_STEP_SIZE;
-		break;
-
-	case GDK_Page_Up:
-		do_scroll = TRUE;
-		if (event->state & GDK_CONTROL_MASK) {
-			xofs = -(width * 3) / 4;
-			yofs = 0;
-		} else {
-			xofs = 0;
-			yofs = -(height * 3) / 4;
-		}
-		break;
-
-	case GDK_Down:
-		do_scroll = TRUE;
-		xofs = 0;
-		yofs = SCROLL_STEP_SIZE;
-		break;
-
-	case GDK_Page_Down:
-		do_scroll = TRUE;
-		if (event->state & GDK_CONTROL_MASK) {
-			xofs = (width * 3) / 4;
-			yofs = 0;
-		} else {
-			xofs = 0;
-			yofs = (height * 3) / 4;
-		}
-		break;
-
-	case GDK_Left:
-		do_scroll = TRUE;
-		xofs = -SCROLL_STEP_SIZE;
-		yofs = 0;
-		break;
-
-	case GDK_Right:
-		do_scroll = TRUE;
-		xofs = SCROLL_STEP_SIZE;
-		yofs = 0;
-		break;
-
-	case GDK_plus:
-	case GDK_equal:
-	case GDK_KP_Add:
-		do_zoom = TRUE;
-		zoom = priv->zoom * priv->zoom_multiplier;
-		break;
-
-	case GDK_minus:
-	case GDK_KP_Subtract:
-		do_zoom = TRUE;
-		zoom = priv->zoom / priv->zoom_multiplier;
-		break;
-
-	case GDK_1:
-		do_zoom = TRUE;
-		zoom = 1.0;
-		break;
-
-	case GDK_F:
-	case GDK_f:
-		set_zoom_fit (view);
-		check_scrollbar_visibility (view, NULL);
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-		break;
-
-	default:
-		return FALSE;
-	}
-
-	if (do_zoom) {
-		gint x, y;
-
-		gdk_window_get_pointer (widget->window, &x, &y, NULL);
-		set_zoom (view, zoom, TRUE, x, y);
-	}
-
-	if (do_scroll)
-		scroll_by (view, xofs, yofs);
-
-	return TRUE;
-}
-
-
-/* Button press event handler for the image view */
-static gboolean
-eog_scroll_view_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	if (!GTK_WIDGET_HAS_FOCUS (priv->display))
-		gtk_widget_grab_focus (GTK_WIDGET (priv->display));
-
-	if (priv->dragging)
-		return FALSE;
-
-	switch (event->button) {
-		case 1:
-		case 2:
-                        if (event->button == 1 && !priv->scroll_wheel_zoom && 
-			    !(event->state & GDK_CONTROL_MASK))
-				break;
-
-			if (is_image_movable (view)) {
-				eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_DRAG);
-
-				priv->dragging = TRUE;
-				priv->drag_anchor_x = event->x;
-				priv->drag_anchor_y = event->y;
-
-				priv->drag_ofs_x = priv->xofs;
-				priv->drag_ofs_y = priv->yofs;
-
-				return TRUE;
-			}
-		default:
-			break;
-	}
-
-	return FALSE;
-}
-
-static void
-eog_scroll_view_style_set (GtkWidget *widget, GtkStyle *old_style)
-{
-	GtkStyle *style;
-	EogScrollViewPrivate *priv;
-
-	style = gtk_widget_get_style (widget);
-	priv = EOG_SCROLL_VIEW (widget)->priv;
-
-	gtk_widget_set_style (priv->display, style);
-}
-
-
-/* Button release event handler for the image view */
-static gboolean
-eog_scroll_view_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	if (!priv->dragging)
-		return FALSE;
-
-	switch (event->button) {
-		case 1:
-		case 2:
-			drag_to (view, event->x, event->y);
-			priv->dragging = FALSE;
-
-			eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_NORMAL);
-			break;
-
-		default:
-			break;
-	}
-
-	return TRUE;
-}
-
-/* Scroll event handler for the image view.  We zoom with an event without
- * modifiers rather than scroll; we use the Shift modifier to scroll.
- * Rationale: images are not primarily vertical, and in EOG you scan scroll by
- * dragging the image with button 1 anyways.
- */
-static gboolean
-eog_scroll_view_scroll_event (GtkWidget *widget, GdkEventScroll *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-	double zoom_factor;
-	int xofs, yofs;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	/* Compute zoom factor and scrolling offsets; we'll only use either of them */
-
-	xofs = priv->hadj->page_increment / 2; /* same as in gtkscrolledwindow.c */
-	yofs = priv->vadj->page_increment / 2;
-
-	switch (event->direction) {
-	case GDK_SCROLL_UP:
-		zoom_factor = priv->zoom_multiplier;
-		xofs = 0;
-		yofs = -yofs;
-		break;
-
-	case GDK_SCROLL_LEFT:
-		zoom_factor = 1.0 / priv->zoom_multiplier;
-		xofs = -xofs;
-		yofs = 0;
-		break;
-
-	case GDK_SCROLL_DOWN:
-		zoom_factor = 1.0 / priv->zoom_multiplier;
-		xofs = 0;
-		yofs = yofs;
-		break;
-
-	case GDK_SCROLL_RIGHT:
-		zoom_factor = priv->zoom_multiplier;
-		xofs = xofs;
-		yofs = 0;
-		break;
-
-	default:
-		g_assert_not_reached ();
-		return FALSE;
-	}
-
-        if (priv->scroll_wheel_zoom) {
-		if (event->state & GDK_SHIFT_MASK)
-			scroll_by (view, yofs, xofs);
-		else if (event->state & GDK_CONTROL_MASK)
-			scroll_by (view, xofs, yofs);
-		else
-			set_zoom (view, priv->zoom * zoom_factor,
-				  TRUE, event->x, event->y);
-	} else {
-		if (event->state & GDK_SHIFT_MASK)
-			scroll_by (view, yofs, xofs);
-		else if (event->state & GDK_CONTROL_MASK)
-			set_zoom (view, priv->zoom * zoom_factor,
-				  TRUE, event->x, event->y);
-		else
-			scroll_by (view, xofs, yofs);
-        }
-
-	return TRUE;
-}
-
-/* Motion event handler for the image view */
-static gboolean
-eog_scroll_view_motion_event (GtkWidget *widget, GdkEventMotion *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-	gint x, y;
-	GdkModifierType mods;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	if (!priv->dragging)
-		return FALSE;
-
-	if (event->is_hint)
-		gdk_window_get_pointer (GTK_WIDGET (priv->display)->window, &x, &y, &mods);
-	else {
-		x = event->x;
-		y = event->y;
-	}
-
-	drag_to (view, x, y);
-	return TRUE;
-}
-
-static void
-display_map_event (GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	eog_debug (DEBUG_WINDOW);
-
-	set_zoom_fit (view);
-	check_scrollbar_visibility (view, NULL);
-	gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-}
-
-static void
-eog_scroll_view_size_allocate (GtkWidget *widget, GtkAllocation *alloc)
-{
-	EogScrollView *view;
-
-	view = EOG_SCROLL_VIEW (widget);
-	check_scrollbar_visibility (view, alloc);
-
-	GTK_WIDGET_CLASS (eog_scroll_view_parent_class)->size_allocate (widget
-									,alloc);
-}
-
-static void
-display_size_change (GtkWidget *widget, GdkEventConfigure *event, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-
-	view = EOG_SCROLL_VIEW (data);
-	priv = view->priv;
-
-	if (priv->zoom_mode == ZOOM_MODE_FIT) {
-		GtkAllocation alloc;
-
-		alloc.width = event->width;
-		alloc.height = event->height;
-
-		set_zoom_fit (view);
-		check_scrollbar_visibility (view, &alloc);
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-	} else {
-		int scaled_width, scaled_height;
-		int x_offset = 0;
-		int y_offset = 0;
-
-		compute_scaled_size (view, priv->zoom, &scaled_width, &scaled_height);
-
-		if (priv->xofs + event->width > scaled_width)
-			x_offset = scaled_width - event->width - priv->xofs;
-
-		if (priv->yofs + event->height > scaled_height)
-			y_offset = scaled_height - event->height - priv->yofs;
-
-		scroll_by (view, x_offset, y_offset);
-	}
-
-	update_scrollbar_values (view);
-}
-
-
-static gboolean
-eog_scroll_view_focus_in_event (GtkWidget     *widget,
-			    GdkEventFocus *event,
-			    gpointer data)
-{
-	g_signal_stop_emission_by_name (G_OBJECT (widget), "focus_in_event");
-	return FALSE;
-}
-
-static gboolean
-eog_scroll_view_focus_out_event (GtkWidget     *widget,
-			     GdkEventFocus *event,
-			     gpointer data)
-{
-	g_signal_stop_emission_by_name (G_OBJECT (widget), "focus_out_event");
-	return FALSE;
-}
-
-/* Expose event handler for the drawing area.  First we process the whole dirty
- * region by drawing a non-interpolated version, which is "instantaneous", and
- * we do this synchronously.  Then, if we are set to use interpolation, we queue
- * an idle handler to handle interpolated drawing there.
- */
-static gboolean
-display_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
-{
-	EogScrollView *view;
-	GdkRectangle *rects;
-	gint n_rects;
-	int i;
-
-	g_return_val_if_fail (GTK_IS_DRAWING_AREA (widget), FALSE);
-	g_return_val_if_fail (event != NULL, FALSE);
-	g_return_val_if_fail (EOG_IS_SCROLL_VIEW (data), FALSE);
-
-	view = EOG_SCROLL_VIEW (data);
-
-	gdk_region_get_rectangles (event->region, &rects, &n_rects);
-
-	for (i = 0; i < n_rects; i++) {
-		request_paint_area (view, rects + i);
-	}
-
-	g_free (rects);
-
-	return TRUE;
-}
-
-
-/*==================================
-
-   image loading callbacks
-
-   -----------------------------------*/
-/*
-static void
-image_loading_update_cb (EogImage *img, int x, int y, int width, int height, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-	GdkRectangle area;
-	int xofs, yofs;
-	int sx0, sy0, sx1, sy1;
-
-	view = (EogScrollView*) data;
-	priv = view->priv;
-
-	eog_debug_message (DEBUG_IMAGE_LOAD, "x: %i, y: %i, width: %i, height: %i\n", 
-			   x, y, width, height);
-
-	if (priv->pixbuf == NULL) {
-		priv->pixbuf = eog_image_get_pixbuf (img);
-		set_zoom_fit (view);
-		check_scrollbar_visibility (view, NULL);
-	}
-	priv->progressive_state = PROGRESSIVE_LOADING;
-
-	get_image_offsets (view, &xofs, &yofs);
-
-	sx0 = floor (x * priv->zoom + xofs);
-	sy0 = floor (y * priv->zoom + yofs);
-	sx1 = ceil ((x + width) * priv->zoom + xofs);
-	sy1 = ceil ((y + height) * priv->zoom + yofs);
-
-	area.x = sx0;
-	area.y = sy0;
-	area.width = sx1 - sx0;
-	area.height = sy1 - sy0;
-
-	if (GTK_WIDGET_DRAWABLE (priv->display))
-		gdk_window_invalidate_rect (GTK_WIDGET (priv->display)->window, &area, FALSE);
-}
-
-
-static void
-image_loading_finished_cb (EogImage *img, gpointer data)
-{
-	EogScrollView *view;
-	EogScrollViewPrivate *priv;
-
-	view = (EogScrollView*) data;
-	priv = view->priv;
-
-	if (priv->pixbuf == NULL) {
-		priv->pixbuf = eog_image_get_pixbuf (img);
-		priv->progressive_state = PROGRESSIVE_NONE;
-		set_zoom_fit (view);
-		check_scrollbar_visibility (view, NULL);
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-
-	}
-	else if (priv->interp_type != GDK_INTERP_NEAREST &&
-		 !is_unity_zoom (view))
-	{
-		// paint antialiased image version 
-		priv->progressive_state = PROGRESSIVE_POLISHING;
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-	}
-}
-
-static void
-image_loading_failed_cb (EogImage *img, char *msg, gpointer data)
-{
-	EogScrollViewPrivate *priv;
-
-	priv = EOG_SCROLL_VIEW (data)->priv;
-
-	g_print ("loading failed: %s.\n", msg);
-
-	if (priv->pixbuf != 0) {
-		g_object_unref (priv->pixbuf);
-		priv->pixbuf = 0;
-	}
-
-	if (GTK_WIDGET_DRAWABLE (priv->display)) {
-		gdk_window_clear (GTK_WIDGET (priv->display)->window);
-	}
-}
-
-static void
-image_loading_cancelled_cb (EogImage *img, gpointer data)
-{
-	EogScrollViewPrivate *priv;
-
-	priv = EOG_SCROLL_VIEW (data)->priv;
-
-	if (priv->pixbuf != NULL) {
-		g_object_unref (priv->pixbuf);
-		priv->pixbuf = NULL;
-	}
-
-	if (GTK_WIDGET_DRAWABLE (priv->display)) {
-		gdk_window_clear (GTK_WIDGET (priv->display)->window);
-	}
-}
-*/
-static void
-image_changed_cb (EogImage *img, gpointer data)
-{
-	EogScrollViewPrivate *priv;
-
-	priv = EOG_SCROLL_VIEW (data)->priv;
-
-	if (priv->pixbuf != NULL) {
-		g_object_unref (priv->pixbuf);
-		priv->pixbuf = NULL;
-	}
-
-	priv->pixbuf = eog_image_get_pixbuf (img);
-
-	set_zoom_fit (EOG_SCROLL_VIEW (data));
-	check_scrollbar_visibility (EOG_SCROLL_VIEW (data), NULL);
-
-	gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-}
-
-/*===================================
-         public API
-  ---------------------------------*/
-
-void
-eog_scroll_view_hide_cursor (EogScrollView *view)
-{
-       eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_HIDDEN);
-}
-
-void
-eog_scroll_view_show_cursor (EogScrollView *view)
-{
-       eog_scroll_view_set_cursor (view, EOG_SCROLL_VIEW_CURSOR_NORMAL);
-}
-
-/* general properties */
-void
-eog_scroll_view_set_zoom_upscale (EogScrollView *view, gboolean upscale)
-{
-	EogScrollViewPrivate *priv;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	priv = view->priv;
-
-	if (priv->upscale != upscale) {
-		priv->upscale = upscale;
-
-		if (priv->zoom_mode == ZOOM_MODE_FIT) {
-			set_zoom_fit (view);
-			gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-		}
-	}
-}
-
-void
-eog_scroll_view_set_antialiasing (EogScrollView *view, gboolean state)
-{
-	EogScrollViewPrivate *priv;
-	GdkInterpType new_interp_type;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	priv = view->priv;
-
-	new_interp_type = state ? GDK_INTERP_BILINEAR : GDK_INTERP_NEAREST;
-
-	if (priv->interp_type != new_interp_type) {
-		priv->interp_type = new_interp_type;
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-	}
-}
-
-void
-eog_scroll_view_set_transparency (EogScrollView *view, EogTransparencyStyle style, GdkColor *color)
-{
-	EogScrollViewPrivate *priv;
-	guint32 col = 0;
-	guint32 red, green, blue;
-	gboolean changed = FALSE;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	priv = view->priv;
-
-	if (color != NULL) {
-		red = (color->red >> 8) << 16;
-		green = (color->green >> 8) << 8;
-		blue = (color->blue >> 8);
-		col = red + green + blue;
-	}
-
-	if (priv->transp_style != style) {
-		priv->transp_style = style;
-		changed = TRUE;
-	}
-
-	if (priv->transp_style == EOG_TRANSP_COLOR && priv->transp_color != col) {
-		priv->transp_color = col;
-		changed = TRUE;
-	}
-
-	if (changed && priv->pixbuf != NULL && gdk_pixbuf_get_has_alpha (priv->pixbuf)) {
-		gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-	}
-}
-
-/* zoom api */
-
-static double preferred_zoom_levels[] = {
-	1.0 / 100, 1.0 / 50, 1.0 / 20,
-	1.0 / 10.0, 1.0 / 5.0, 1.0 / 3.0, 1.0 / 2.0, 1.0 / 1.5,
-        1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0,
-        11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0
-};
-static const gint n_zoom_levels = (sizeof (preferred_zoom_levels) / sizeof (double));
-
-void
-eog_scroll_view_zoom_in (EogScrollView *view, gboolean smooth)
-{
-	EogScrollViewPrivate *priv;
-	double zoom;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	priv = view->priv;
-
-	if (smooth) {
-		zoom = priv->zoom * priv->zoom_multiplier;
-	}
-	else {
-		int i;
-		int index = -1;
-
-		for (i = 0; i < n_zoom_levels; i++) {
-			if (preferred_zoom_levels [i] - priv->zoom
-					> DOUBLE_EQUAL_MAX_DIFF) {
-				index = i;
-				break;
-			}
-		}
-
-		if (index == -1) {
-			zoom = priv->zoom;
-		}
-		else {
-			zoom = preferred_zoom_levels [i];
-		}
-	}
-	set_zoom (view, zoom, FALSE, 0, 0);
-
-}
-
-void
-eog_scroll_view_zoom_out (EogScrollView *view, gboolean smooth)
-{
-	EogScrollViewPrivate *priv;
-	double zoom;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	priv = view->priv;
-
-	if (smooth) {
-		zoom = priv->zoom / priv->zoom_multiplier;
-	}
-	else {
-		int i;
-		int index = -1;
-
-		for (i = n_zoom_levels - 1; i >= 0; i--) {
-			if (priv->zoom - preferred_zoom_levels [i]
-					> DOUBLE_EQUAL_MAX_DIFF) {
-				index = i;
-				break;
-			}
-		}
-		if (index == -1) {
-			zoom = priv->zoom;
-		}
-		else {
-			zoom = preferred_zoom_levels [i];
-		}
-	}
-	set_zoom (view, zoom, FALSE, 0, 0);
-}
-
-void
-eog_scroll_view_zoom_fit (EogScrollView *view)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	set_zoom_fit (view);
-	check_scrollbar_visibility (view, NULL);
-	gtk_widget_queue_draw (GTK_WIDGET (view->priv->display));
-}
-
-void
-eog_scroll_view_set_zoom (EogScrollView *view, double zoom)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	set_zoom (view, zoom, FALSE, 0, 0);
-}
-
-double
-eog_scroll_view_get_zoom (EogScrollView *view)
-{
-	g_return_val_if_fail (EOG_IS_SCROLL_VIEW (view), 0.0);
-
-	return view->priv->zoom;
-}
-
-gboolean
-eog_scroll_view_get_zoom_is_min (EogScrollView *view)
-{
-	g_return_val_if_fail (EOG_IS_SCROLL_VIEW (view), FALSE);
-
-	set_minimum_zoom_factor (view);
-
-	return DOUBLE_EQUAL (view->priv->zoom, MIN_ZOOM_FACTOR) || 
-	       DOUBLE_EQUAL (view->priv->zoom, view->priv->min_zoom);
-}
-
-gboolean
-eog_scroll_view_get_zoom_is_max (EogScrollView *view)
-{
-	g_return_val_if_fail (EOG_IS_SCROLL_VIEW (view), FALSE);
-
-	return DOUBLE_EQUAL (view->priv->zoom, MAX_ZOOM_FACTOR);
-}
-
-void
-eog_scroll_view_set_image (EogScrollView *view, EogImage *image)
-{
-	EogScrollViewPrivate *priv;
-
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	priv = view->priv;
-
-	if (priv->image == image) {
-		return;
-	}
-
-	if (priv->image != NULL) {
-		free_image_resources (view);
-		if (GTK_WIDGET_DRAWABLE (priv->display) && image == NULL) {
-			gdk_window_clear (GTK_WIDGET (priv->display)->window);
-		}
-	}
-	g_assert (priv->image == NULL);
-	g_assert (priv->pixbuf == NULL);
-
-	priv->progressive_state = PROGRESSIVE_NONE;
-	if (image != NULL) {
-		eog_image_data_ref (image);
-
-		if (priv->pixbuf == NULL) {
-			priv->pixbuf = eog_image_get_pixbuf (image);
-			priv->progressive_state = PROGRESSIVE_NONE;
-			set_zoom_fit (view);
-			check_scrollbar_visibility (view, NULL);
-			gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-
-		}
-		else if (priv->interp_type != GDK_INTERP_NEAREST &&
-			 !is_unity_zoom (view))
-		{
-			/* paint antialiased image version */
-			priv->progressive_state = PROGRESSIVE_POLISHING;
-			gtk_widget_queue_draw (GTK_WIDGET (priv->display));
-		}
-
-		priv->image_changed_id = g_signal_connect (image, "changed",
-							   (GCallback) image_changed_cb, view);
-	}
-	
-	priv->image = image;
-}
-
-gboolean 
-eog_scroll_view_scrollbars_visible (EogScrollView *view)
-{
-	if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (view->priv->hbar)) && 
-	    !GTK_WIDGET_VISIBLE (GTK_WIDGET (view->priv->vbar)))
-		return FALSE;
-
-	return TRUE;
-}
-
-/*===================================
-    object creation/freeing
-  ---------------------------------*/
-
-
-static void
 eog_scroll_view_init (EogScrollView *view)
@@ -1907,26 +67,10 @@
 	EogScrollViewPrivate *priv;
 
 	priv = view->priv = EOG_SCROLL_VIEW_GET_PRIVATE (view);
-
-	priv->zoom = 1.0;
-	priv->min_zoom = MIN_ZOOM_FACTOR;
-	priv->zoom_mode = ZOOM_MODE_FIT;
-	priv->upscale = FALSE;
-	priv->uta = NULL;
-	priv->interp_type = GDK_INTERP_BILINEAR;
-	priv->scroll_wheel_zoom = FALSE;
-	priv->zoom_multiplier = IMAGE_VIEW_ZOOM_MULTIPLIER;
-	priv->image = NULL;
-	priv->pixbuf = NULL;
-	priv->progressive_state = PROGRESSIVE_NONE;
-	priv->transp_style = EOG_TRANSP_BACKGROUND;
-	priv->transp_color = 0;
-	priv->cursor = EOG_SCROLL_VIEW_CURSOR_NORMAL;
-	priv->menu = NULL;
 }
 
 static void
-eog_scroll_view_dispose (GObject *object)
+eog_scroll_view_finalize (GObject *object)
 {
 	EogScrollView *view;
 	EogScrollViewPrivate *priv;
@@ -1936,199 +80,24 @@
 	view = EOG_SCROLL_VIEW (object);
 	priv = view->priv;
 	
-	if (priv->uta != NULL) {
-		art_uta_free (priv->uta);
-		priv->uta = NULL;
-	}
 
-	if (priv->idle_id != 0) {
-		g_source_remove (priv->idle_id);
-		priv->idle_id = 0;
-	}
-
-	free_image_resources (view);
-
-	G_OBJECT_CLASS (eog_scroll_view_parent_class)->dispose (object);
+	G_OBJECT_CLASS (eog_scroll_view_parent_class)->finalize (object);
 }
 
-static void
-eog_scroll_view_class_init (EogScrollViewClass *klass)
-{
-	GObjectClass *gobject_class;
-	GtkWidgetClass *widget_class;
-
-	gobject_class = (GObjectClass*) klass;
-	widget_class = (GtkWidgetClass*) klass;
-
-	gobject_class->dispose = eog_scroll_view_dispose;
-
-	view_signals [SIGNAL_ZOOM_CHANGED] =
-		g_signal_new ("zoom_changed",
-			      EOG_TYPE_SCROLL_VIEW,
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (EogScrollViewClass, zoom_changed),
-			      NULL, NULL,
-			      eog_marshal_VOID__DOUBLE,
-			      G_TYPE_NONE, 1,
-			      G_TYPE_DOUBLE);
-
-	widget_class->size_allocate = eog_scroll_view_size_allocate;
-	widget_class->style_set = eog_scroll_view_style_set;
-
-	g_type_class_add_private (klass, sizeof (EogScrollViewPrivate));
-}
-
-
 GtkWidget*
 eog_scroll_view_new (void)
 {
 	GtkWidget *widget;
-	GtkTable *table;
 	EogScrollView *view;
 	EogScrollViewPrivate *priv;
 
 	widget = g_object_new (EOG_TYPE_SCROLL_VIEW,
-			       "can-focus", TRUE,
-			       "n_rows", 2,
-			       "n_columns", 2,
-			       "homogeneous", FALSE,
 			       NULL);
 
-	table = GTK_TABLE (widget);
 	view = EOG_SCROLL_VIEW (widget);
 	priv = view->priv;
 
-	priv->hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 100, 0, 10, 10, 100));
-	g_signal_connect (priv->hadj, "value_changed",
-			  G_CALLBACK (adjustment_changed_cb),
-			  view);
-	priv->hbar = gtk_hscrollbar_new (priv->hadj);
-	priv->vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0, 100, 0, 10, 10, 100));
-	g_signal_connect (priv->vadj, "value_changed",
-			  G_CALLBACK (adjustment_changed_cb),
-			  view);
-	priv->vbar = gtk_vscrollbar_new (priv->vadj);
-	priv->display = g_object_new (GTK_TYPE_DRAWING_AREA,
-				      "can-focus", TRUE,
-				      NULL);
-	/* We don't want to be double-buffered as we are SuperSmart(tm) */
-	gtk_widget_set_double_buffered (GTK_WIDGET (priv->display), FALSE);
-
-	gtk_widget_add_events (GTK_WIDGET (priv->display),
-			       GDK_EXPOSURE_MASK
-			       | GDK_BUTTON_PRESS_MASK
-			       | GDK_BUTTON_RELEASE_MASK
-			       | GDK_POINTER_MOTION_MASK
-			       | GDK_POINTER_MOTION_HINT_MASK
-			       | GDK_SCROLL_MASK
-			       | GDK_KEY_PRESS_MASK);
-	g_signal_connect (G_OBJECT (priv->display), "configure_event", G_CALLBACK (display_size_change), view);
-	g_signal_connect (G_OBJECT (priv->display), "expose_event", G_CALLBACK (display_expose_event), view);
-	g_signal_connect (G_OBJECT (priv->display), "map_event", G_CALLBACK (display_map_event), view);
-	g_signal_connect (G_OBJECT (priv->display), "button_press_event", G_CALLBACK (eog_scroll_view_button_press_event), view);
-	g_signal_connect (G_OBJECT (priv->display), "motion_notify_event", G_CALLBACK (eog_scroll_view_motion_event), view);
-	g_signal_connect (G_OBJECT (priv->display), "button_release_event", G_CALLBACK (eog_scroll_view_button_release_event), view);
-	g_signal_connect (G_OBJECT (priv->display), "scroll_event", G_CALLBACK (eog_scroll_view_scroll_event), view);
-	g_signal_connect (G_OBJECT (priv->display), "focus_in_event", G_CALLBACK (eog_scroll_view_focus_in_event), NULL);
-	g_signal_connect (G_OBJECT (priv->display), "focus_out_event", G_CALLBACK (eog_scroll_view_focus_out_event), NULL);
-
-	g_signal_connect (G_OBJECT (widget), "key_press_event", G_CALLBACK (display_key_press_event), view);
-
-	gtk_table_attach (table, priv->display,
-			  0, 1, 0, 1,
-			  GTK_EXPAND | GTK_FILL,
-			  GTK_EXPAND | GTK_FILL,
-			  0,0);
-	gtk_table_attach (table, priv->hbar,
-			  0, 1, 1, 2,
-			  GTK_FILL,
-			  GTK_FILL,
-			  0, 0);
-	gtk_table_attach (table, priv->vbar,
-			  1, 2, 0, 1,
-			  GTK_FILL, GTK_FILL,
-			  0, 0);
-
 	gtk_widget_show_all (widget);
 	
 	return widget;
 }
-
-static void 
-eog_scroll_view_popup_menu (EogScrollView *view, GdkEventButton *event)
-{
-	GtkWidget *popup;
-	int button, event_time;
-
-	popup = view->priv->menu;
-	
-	if (event) {
-		button = event->button;
-		event_time = event->time;
-	} else {
-		button = 0;
-		event_time = gtk_get_current_event_time ();
-	}
-	
-	gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
-			button, event_time);
-}
-
-static gboolean
-view_on_button_press_event_cb (GtkWidget *view, GdkEventButton *event, 
-			       gpointer user_data)
-{    
-    /* Ignore double-clicks and triple-clicks */
-    if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
-    {
-	    eog_scroll_view_popup_menu (EOG_SCROLL_VIEW (view), event);
-
-	    return TRUE;
-    }
-    
-    return FALSE;
-}
-
-void
-eog_scroll_view_set_popup (EogScrollView *view,
-			   GtkMenu *menu)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-	g_return_if_fail (view->priv->menu == NULL);
-
-	view->priv->menu = g_object_ref (menu);
-
-	gtk_menu_attach_to_widget (GTK_MENU (view->priv->menu), 
-				   GTK_WIDGET (view), 
-				   NULL);
-
-	g_signal_connect (G_OBJECT (view), "button_press_event",
-			  G_CALLBACK (view_on_button_press_event_cb), NULL);
-}
-
-void
-eog_scroll_view_set_bg_color (EogScrollView *view,
-			      GdkColor *color)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-	gtk_widget_modify_bg (GTK_WIDGET (view), GTK_STATE_NORMAL, color);
-}
-
-void
-eog_scroll_view_set_scroll_wheel_zoom (EogScrollView *view, 
-				       gboolean       scroll_wheel_zoom)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-        view->priv->scroll_wheel_zoom = scroll_wheel_zoom;
-}
-
-void
-eog_scroll_view_set_zoom_multiplier (EogScrollView *view, 
-				     gdouble        zoom_multiplier)
-{
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (view));
-
-        view->priv->zoom_multiplier = 1.0 + zoom_multiplier;
-}
Index: src/eog-window.c
===================================================================
--- src/eog-window.c	(revisión: 4685)
+++ src/eog-window.c	(copia de trabajo)
@@ -32,6 +32,7 @@
 #include <math.h>
 
 #include "eog-window.h"
+#include "eog-view.h"
 #include "eog-scroll-view.h"
 #include "eog-debug.h"
 #include "eog-file-chooser.h"
@@ -234,13 +235,13 @@
 
 	priv = EOG_WINDOW (user_data)->priv;
 
-	g_return_if_fail (EOG_IS_SCROLL_VIEW (priv->view));
+	g_return_if_fail (EOG_IS_VIEW (priv->view));
 
 	if (entry->value != NULL && entry->value->type == GCONF_VALUE_BOOL) {
 		interpolate = gconf_value_get_bool (entry->value);
 	}
 
-	eog_scroll_view_set_antialiasing (EOG_SCROLL_VIEW (priv->view), 
+	eog_view_set_antialiasing (EOG_VIEW (priv->view), 
 					  interpolate);
 }
 
@@ -265,7 +266,7 @@
 		scroll_wheel_zoom = gconf_value_get_bool (entry->value);
 	}
 
-	eog_scroll_view_set_scroll_wheel_zoom (EOG_SCROLL_VIEW (priv->view), 
+	eog_view_set_scroll_wheel_zoom (EOG_VIEW (priv->view), 
 					       scroll_wheel_zoom);
 }
 
@@ -290,7 +291,7 @@
 		multiplier = gconf_value_get_float (entry->value);
 	}
 
-	eog_scroll_view_set_zoom_multiplier (EOG_SCROLL_VIEW (priv->view), 
+	eog_view_set_zoom_multiplier (EOG_VIEW (priv->view), 
 					     multiplier);
 }
 
@@ -324,15 +325,15 @@
 		color_str = gconf_client_get_string (priv->client,
 						     EOG_CONF_VIEW_TRANS_COLOR, NULL);
 		if (gdk_color_parse (color_str, &color)) {
-			eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
+			eog_view_set_transparency (EOG_VIEW (priv->view),
 							  EOG_TRANSP_COLOR, &color);
 		}
 		g_free (color_str);
 	} else if (g_ascii_strcasecmp (value, "CHECK_PATTERN") == 0) {
-		eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
+		eog_view_set_transparency (EOG_VIEW (priv->view),
 						  EOG_TRANSP_CHECKED, NULL);
 	} else {
-		eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
+		eog_view_set_transparency (EOG_VIEW (priv->view),
 						  EOG_TRANSP_BACKGROUND, NULL);
 	}
 }
@@ -369,7 +370,7 @@
 		color_str = gconf_value_get_string (entry->value);
 
 		if (gdk_color_parse (color_str, &color)) {
-			eog_scroll_view_set_transparency (EOG_SCROLL_VIEW (priv->view),
+			eog_view_set_transparency (EOG_VIEW (priv->view),
 							  EOG_TRANSP_COLOR, &color);
 		}
 	}
@@ -701,7 +702,7 @@
 		int zoom, width, height;
 		goffset bytes = 0;
 
-		zoom = floor (100 * eog_scroll_view_get_zoom (EOG_SCROLL_VIEW (priv->view)) + 0.5);
+		zoom = floor (100 * eog_view_get_zoom (EOG_VIEW (priv->view)) + 0.5);
 
 		eog_image_get_size (priv->image, &width, &height);
 
@@ -1026,7 +1027,7 @@
 		image_thumb_changed_cb (image, window);
 	}
 
-	eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), image);
+	eog_view_set_image (EOG_VIEW (priv->view), image);
 
 	gtk_window_set_title (GTK_WINDOW (window), eog_image_get_caption (image));
 
@@ -1420,7 +1421,7 @@
 
 		update_status_bar (window);
 
-		eog_scroll_view_set_image (EOG_SCROLL_VIEW (priv->view), NULL);
+		eog_view_set_image (EOG_VIEW (priv->view), NULL);
 
         	if (window->priv->status == EOG_WINDOW_STATUS_INIT) {
 			update_action_groups_state (window);
@@ -1615,9 +1616,9 @@
 					     "ViewZoomOut");
 
 	gtk_action_set_sensitive (action_zoom_in,
-			!eog_scroll_view_get_zoom_is_max (EOG_SCROLL_VIEW (window->priv->view)));
+			!eog_view_get_zoom_is_max (EOG_VIEW (window->priv->view)));
 	gtk_action_set_sensitive (action_zoom_out,
-			!eog_scroll_view_get_zoom_is_min (EOG_SCROLL_VIEW (window->priv->view)));
+			!eog_view_get_zoom_is_min (EOG_VIEW (window->priv->view)));
 }
 
 static void
@@ -1749,7 +1750,7 @@
 
 	gtk_widget_hide_all (window->priv->fullscreen_popup);
 
-	eog_scroll_view_hide_cursor (EOG_SCROLL_VIEW (window->priv->view));
+	eog_view_hide_cursor (EOG_VIEW (window->priv->view));
 
 	fullscreen_clear_timeout (window);
 
@@ -1818,7 +1819,7 @@
 
 	window->priv->fullscreen_timeout_source = source;
 
-	eog_scroll_view_show_cursor (EOG_SCROLL_VIEW (window->priv->view));
+	eog_view_show_cursor (EOG_VIEW (window->priv->view));
 }
 
 static void
@@ -2115,12 +2116,12 @@
 					 EOG_CONF_FULLSCREEN_UPSCALE, 
 					 NULL);
 
-	eog_scroll_view_set_zoom_upscale (EOG_SCROLL_VIEW (priv->view), 
+	eog_view_set_zoom_upscale (EOG_VIEW (priv->view), 
 					  upscale);
 
 	gtk_widget_grab_focus (priv->view);
 
-	eog_scroll_view_set_bg_color (EOG_SCROLL_VIEW (window->priv->view),
+	eog_view_set_bg_color (EOG_VIEW (window->priv->view),
 				      &(GTK_WIDGET (window)->style->black));
 
 	{
@@ -2195,9 +2196,9 @@
 	g_assert (GTK_IS_WIDGET (menubar));
 	gtk_widget_show (menubar);
 	
-	eog_scroll_view_set_zoom_upscale (EOG_SCROLL_VIEW (priv->view), FALSE);
+	eog_view_set_zoom_upscale (EOG_VIEW (priv->view), FALSE);
 
-	eog_scroll_view_set_bg_color (EOG_SCROLL_VIEW (window->priv->view), NULL);
+	eog_view_set_bg_color (EOG_VIEW (window->priv->view), NULL);
 	gtk_widget_set_style (window->priv->view->parent, NULL);
 	gtk_window_unfullscreen (GTK_WINDOW (window));
 
@@ -2207,7 +2208,7 @@
 		eog_window_update_fullscreen_action (window);
 	}
 
-	eog_scroll_view_show_cursor (EOG_SCROLL_VIEW (priv->view));
+	eog_view_show_cursor (EOG_VIEW (priv->view));
 
 #ifdef HAVE_DBUS
 	eog_application_screensaver_enable (EOG_APP);
@@ -3120,7 +3121,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_zoom_in (EOG_SCROLL_VIEW (priv->view), FALSE);
+		eog_view_zoom_in (EOG_VIEW (priv->view), FALSE);
 	}
 }
 
@@ -3136,7 +3137,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_zoom_out (EOG_SCROLL_VIEW (priv->view), FALSE);
+		eog_view_zoom_out (EOG_VIEW (priv->view), FALSE);
 	}
 }
 
@@ -3152,7 +3153,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_set_zoom (EOG_SCROLL_VIEW (priv->view), 1.0);
+		eog_view_set_zoom (EOG_VIEW (priv->view), 1.0);
 	}
 }
 
@@ -3168,7 +3169,7 @@
 	priv = EOG_WINDOW (user_data)->priv;
 
 	if (priv->view) {
-		eog_scroll_view_zoom_fit (EOG_SCROLL_VIEW (priv->view));
+		eog_view_zoom_fit (EOG_VIEW (priv->view));
 	}
 }
 
@@ -3861,7 +3862,7 @@
 			  window);
 
 	view_popup = gtk_ui_manager_get_widget (priv->ui_mgr, "/ViewPopup");
-	eog_scroll_view_set_popup (EOG_SCROLL_VIEW (priv->view),
+	eog_view_set_popup (EOG_VIEW (priv->view),
 				   GTK_MENU (view_popup));
 
 	frame = gtk_widget_new (GTK_TYPE_FRAME, 
@@ -4288,7 +4289,7 @@
 			break;
 		} /* else fall-trough is intended */
 	case GDK_Up:
-		if (eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) {
+		if (eog_view_scrollbars_visible (EOG_VIEW (EOG_WINDOW (widget)->priv->view))) {
 			/* break to let scrollview handle the key */
 			break;
 		}
@@ -4307,7 +4308,7 @@
 			break;
 		} /* else fall-trough is intended */
 	case GDK_Down:
-		if (eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) {
+		if (eog_view_scrollbars_visible (EOG_VIEW (EOG_WINDOW (widget)->priv->view))) {
 			/* break to let scrollview handle the key */
 			break;
 		}
@@ -4319,7 +4320,7 @@
 			break;
 		}
 	case GDK_Page_Up:
-		if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) {
+		if (!eog_view_scrollbars_visible (EOG_VIEW (EOG_WINDOW (widget)->priv->view))) {
 			if (!GTK_WIDGET_VISIBLE (EOG_WINDOW (widget)->priv->nav)) {
 				/* If the iconview is not visible skip to the 
 				 * previous image manually as it won't handle
@@ -4332,7 +4333,7 @@
 		}
 		break;
 	case GDK_Page_Down:
-		if (!eog_scroll_view_scrollbars_visible (EOG_SCROLL_VIEW (EOG_WINDOW (widget)->priv->view))) {
+		if (!eog_view_scrollbars_visible (EOG_VIEW (EOG_WINDOW (widget)->priv->view))) {
 			if (!GTK_WIDGET_VISIBLE (EOG_WINDOW (widget)->priv->nav)) {
 				/* If the iconview is not visible skip to the 
 				 * next image manually as it won't handle
Index: src/eog-view.c
===================================================================
--- src/eog-view.c	(revisión: 0)
+++ src/eog-view.c	(revisión: 0)
@@ -0,0 +1,410 @@
+/* Eye of GNOME -- Image Viewing Widget
+ *
+ * Copyright (C) 2008 The Free Software Foundation
+ *
+ * Author: Javier Sanchez  <jsanchez@deskblue.com>
+ *
+ * Based on code by:
+ *      - Lucas Rocha       <lucasr@gnome.org>
+ * 	- Claudio Saavedra  <csaavedra@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "eog-view.h"
+
+/* --- Private part of the EogView structure --- */
+struct _EogViewPrivate
+{
+	GtkWidget *display;
+};
+
+#define EOG_VIEW_GET_PRIVATE(object) \
+	(G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_VIEW, EogViewPrivate))
+
+G_DEFINE_ABSTRACT_TYPE (EogView, eog_view, GTK_TYPE_BIN)
+
+/* --- Object creation --- */
+static void       eog_view_class_init                 (EogViewClass *klass);
+static void       eog_view_init                       (EogView *view);
+static void       eog_view_finalize                   (GObject *object);
+
+/* --- Properties management --- */
+static void       eog_view_get_property               (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void       eog_view_set_property               (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+
+/* --- Old API --- */
+static void       eog_view_real_set_image             (EogView *view, EogImage *image);
+
+static void       eog_view_real_set_scroll_wheel_zoom (EogView *view, gboolean scroll_wheel_zoom);
+static void       eog_view_real_set_zoom_upscale      (EogView *view, gboolean upscale);
+static void       eog_view_real_set_zoom_multiplier   (EogView *view, gdouble multiplier);
+static void       eog_view_real_set_antialiasing      (EogView *view, gboolean state);
+static void       eog_view_real_set_transparency      (EogView *view, EogTransparencyStyle style, GdkColor *color);
+static gboolean   eog_view_real_scrollbars_visible    (EogView *view);
+static void	  eog_view_real_set_popup             (EogView *view, GtkMenu *menu);
+static void	  eog_view_real_set_bg_color          (EogView *view, GdkColor *color);
+
+static void       eog_view_real_zoom_in               (EogView *view, gboolean smooth);
+static void       eog_view_real_zoom_out              (EogView *view, gboolean smooth);
+static void       eog_view_real_zoom_fit              (EogView *view);
+static void       eog_view_real_set_zoom              (EogView *view, double zoom);
+static double     eog_view_real_get_zoom              (EogView *view);
+static gboolean   eog_view_real_get_zoom_is_min       (EogView *view);
+static gboolean   eog_view_real_get_zoom_is_max       (EogView *view);
+static void       eog_view_real_show_cursor           (EogView *view);
+static void       eog_view_real_hide_cursor           (EogView *view);
+
+/* --- Object creation --- */
+static void
+eog_view_class_init (EogViewClass *klass)
+{
+	GObjectClass *gobject_class;
+
+	gobject_class = (GObjectClass*) klass;
+
+	gobject_class->get_property  = eog_view_get_property;
+	gobject_class->set_property  = eog_view_set_property;
+	gobject_class->finalize      = eog_view_finalize;
+	
+	klass->set_image             = eog_view_real_set_image;
+	klass->set_scroll_wheel_zoom = eog_view_real_set_scroll_wheel_zoom;
+	klass->set_zoom_upscale      = eog_view_real_set_zoom_upscale;
+	klass->set_zoom_multiplier   = eog_view_real_set_zoom_multiplier;
+	klass->set_antialiasing      = eog_view_real_set_antialiasing;
+	klass->set_transparency      = eog_view_real_set_transparency;
+	klass->scrollbars_visible    = eog_view_real_scrollbars_visible;
+	klass->set_popup             = eog_view_real_set_popup;
+	klass->set_bg_color          = eog_view_real_set_bg_color;
+	klass->zoom_in               = eog_view_real_zoom_in;
+	klass->zoom_out              = eog_view_real_zoom_out;
+	klass->zoom_fit              = eog_view_real_zoom_fit;
+	klass->set_zoom              = eog_view_real_set_zoom;
+	klass->get_zoom              = eog_view_real_get_zoom;
+	klass->get_zoom_is_min       = eog_view_real_get_zoom_is_min;
+	klass->get_zoom_is_max       = eog_view_real_get_zoom_is_max;
+	klass->show_cursor           = eog_view_real_show_cursor;
+	klass->hide_cursor           = eog_view_real_hide_cursor;
+
+	g_type_class_add_private (klass, sizeof (EogViewPrivate));
+}
+
+static void
+eog_view_init (EogView *view)
+{
+	EogViewPrivate *priv;
+
+	view->priv = priv = EOG_VIEW_GET_PRIVATE (view);
+
+	/* Initialize atributes */
+}
+
+static void
+eog_view_finalize (GObject *object)
+{
+	EogView *view;
+	EogViewPrivate *priv;
+
+	g_return_if_fail (EOG_IS_VIEW (object));
+
+	view = EOG_VIEW (object);
+	priv = view->priv;
+	
+	G_OBJECT_CLASS (eog_view_parent_class)->finalize (object);
+}
+
+/* --- Properties management --- */
+static void
+eog_view_get_property (GObject    *object,
+		       guint       prop_id,
+		       GValue     *value,
+		       GParamSpec *pspec)
+{
+	EogViewPrivate *priv = EOG_VIEW_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+static void
+eog_view_set_property (GObject      *object,
+		       guint         prop_id,
+		       const GValue *value,
+		       GParamSpec   *pspec)
+{
+	EogViewPrivate *priv = EOG_VIEW_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	}
+}
+
+/* --- Old API --- */
+void
+eog_view_set_image (EogView *view, EogImage *image)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+	g_return_if_fail (!image || EOG_IS_IMAGE (image));
+
+	EOG_VIEW_GET_CLASS (view)->set_image (view, image);
+}
+
+static void
+eog_view_real_set_image (EogView *view, EogImage *image)
+{
+	g_warning ("EogView::set_image not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_scroll_wheel_zoom (EogView *view, gboolean scroll_wheel_zoom)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->set_scroll_wheel_zoom (view, scroll_wheel_zoom);
+}
+
+static void
+eog_view_real_set_scroll_wheel_zoom (EogView *view, gboolean scroll_wheel_zoom)
+{
+	g_warning ("EogView::set_scroll_wheel_zoom not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_zoom_upscale (EogView *view, gboolean upscale)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+        EOG_VIEW_GET_CLASS (view)->set_zoom_upscale (view, upscale);
+}
+
+static void
+eog_view_real_set_zoom_upscale (EogView *view, gboolean upscale)
+{
+	g_warning ("EogView::set_zoom_upscale not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_zoom_multiplier (EogView *view, gdouble zoom_multiplier)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->set_zoom_multiplier (view, zoom_multiplier);
+}
+
+static void
+eog_view_real_set_zoom_multiplier (EogView *view, gdouble zoom_multiplier)
+{
+	g_warning ("EogView::set_zoom_multiplier not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_antialiasing (EogView *view, gboolean state)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->set_antialiasing (view, state);
+}
+
+static void
+eog_view_real_set_antialiasing (EogView *view, gboolean state)
+{
+	g_warning ("EogView::set_antialiasing not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_transparency (EogView *view, EogTransparencyStyle style, GdkColor *color)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->set_transparency (view, style, color);
+}
+
+static void
+eog_view_real_set_transparency (EogView *view, EogTransparencyStyle style, GdkColor *color)
+{
+	g_warning ("EogView::set_transparency not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+gboolean
+eog_view_scrollbars_visible (EogView *view)
+{
+	g_return_val_if_fail (EOG_IS_VIEW (view), FALSE);
+
+	return EOG_VIEW_GET_CLASS (view)->scrollbars_visible (view);
+}
+
+static gboolean
+eog_view_real_scrollbars_visible (EogView *view)
+{
+	g_warning ("EogView::scrollbars_visible not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_popup (EogView *view, GtkMenu *menu)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+	g_return_if_fail (GTK_IS_MENU (menu));
+
+	EOG_VIEW_GET_CLASS (view)->set_popup (view, menu);
+}
+
+static void
+eog_view_real_set_popup (EogView *view, GtkMenu *menu)
+{
+	g_warning ("EogView::set_popup not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_bg_color (EogView *view, GdkColor *color)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->set_bg_color (view, color);
+}
+
+static void
+eog_view_real_set_bg_color (EogView *view, GdkColor *color)
+{
+	g_warning ("EogView::set_bg_color not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_zoom_in (EogView *view, gboolean smooth)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->zoom_in (view, smooth);
+}
+
+static void
+eog_view_real_zoom_in (EogView *view, gboolean smooth)
+{
+	g_warning ("EogView::zoom_in not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_zoom_out (EogView *view, gboolean smooth)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->zoom_out (view, smooth);
+}
+
+static void
+eog_view_real_zoom_out (EogView *view, gboolean smooth)
+{
+	g_warning ("EogView::zoom_out not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_zoom_fit (EogView *view)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->zoom_fit (view);
+}
+
+static void
+eog_view_real_zoom_fit (EogView *view)
+{
+	g_warning ("EogView::zoom_fit not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_set_zoom (EogView *view, gdouble zoom)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->set_zoom (view, zoom);
+}
+
+static void
+eog_view_real_set_zoom (EogView *view, gdouble zoom)
+{
+	g_warning ("EogView::set_zoom not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+gdouble
+eog_view_get_zoom (EogView *view)
+{
+	g_return_val_if_fail (EOG_IS_VIEW (view), 0.0);
+
+	return EOG_VIEW_GET_CLASS (view)->get_zoom (view);
+}
+
+static gdouble
+eog_view_real_get_zoom (EogView *view)
+{
+	g_warning ("EogView::get_zoom not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+gboolean
+eog_view_get_zoom_is_min  (EogView *view)
+{
+	g_return_val_if_fail (EOG_IS_VIEW (view), FALSE);
+
+	return EOG_VIEW_GET_CLASS (view)->get_zoom_is_min (view);
+}
+
+static gboolean
+eog_view_real_get_zoom_is_min  (EogView *view)
+{
+	g_warning ("EogView::get_zoom_is_min not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+gboolean
+eog_view_get_zoom_is_max (EogView *view)
+{
+	g_return_val_if_fail (EOG_IS_VIEW (view), FALSE);
+
+	return EOG_VIEW_GET_CLASS (view)->get_zoom_is_max (view);
+}
+
+static gboolean
+eog_view_real_get_zoom_is_max (EogView *view)
+{
+	g_warning ("EogView::get_zoom_is_max not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_show_cursor (EogView *view)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->show_cursor (view);
+}
+
+static void
+eog_view_real_show_cursor (EogView *view)
+{
+	g_warning ("EogView::show_cursor not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
+
+void
+eog_view_hide_cursor (EogView *view)
+{
+	g_return_if_fail (EOG_IS_VIEW (view));
+
+	EOG_VIEW_GET_CLASS (view)->hide_cursor (view);
+}
+
+static void
+eog_view_real_hide_cursor (EogView *view)
+{
+	g_warning ("EogView::hide_cursor not implemented for `%s'", g_type_name (G_TYPE_FROM_INSTANCE (view)));
+}
Index: src/eog-scroll-view.h
===================================================================
--- src/eog-scroll-view.h	(revisión: 4685)
+++ src/eog-scroll-view.h	(copia de trabajo)
@@ -1,8 +1,7 @@
 #ifndef _EOG_SCROLL_VIEW_H_
 #define _EOG_SCROLL_VIEW_H_
 
-#include <gtk/gtk.h>
-#include "eog-image.h"
+#include "eog-view.h"
 
 G_BEGIN_DECLS
 
@@ -18,50 +17,18 @@
 
 
 struct _EogScrollView {
-	GtkTable  widget;
+	EogView view;
 
 	EogScrollViewPrivate *priv;
 };
 
 struct _EogScrollViewClass {
-	GtkTableClass parent_class;
-
-	void (* zoom_changed) (EogScrollView *view, double zoom);
+	EogViewClass parent_class;
 };
 
-typedef enum {
-	EOG_TRANSP_BACKGROUND,
-	EOG_TRANSP_CHECKED,
-	EOG_TRANSP_COLOR
-} EogTransparencyStyle;
+GType      eog_scroll_view_get_type         (void) G_GNUC_CONST;
+GtkWidget *eog_scroll_view_new              (void);
 
-GType    eog_scroll_view_get_type         (void) G_GNUC_CONST;
-GtkWidget* eog_scroll_view_new            (void);
-
-/* loading stuff */
-void     eog_scroll_view_set_image        (EogScrollView *view, EogImage *image);
-
-/* general properties */
-void     eog_scroll_view_set_scroll_wheel_zoom (EogScrollView *view, gboolean scroll_wheel_zoom);
-void     eog_scroll_view_set_zoom_upscale (EogScrollView *view, gboolean upscale);
-void     eog_scroll_view_set_zoom_multiplier (EogScrollView *view, gdouble multiplier);
-void     eog_scroll_view_set_antialiasing (EogScrollView *view, gboolean state);
-void     eog_scroll_view_set_transparency (EogScrollView *view, EogTransparencyStyle style, GdkColor *color);
-gboolean eog_scroll_view_scrollbars_visible (EogScrollView *view);
-void	 eog_scroll_view_set_popup (EogScrollView *view, GtkMenu *menu);
-void	 eog_scroll_view_set_bg_color (EogScrollView *view, GdkColor *color);
-
-/* zoom api */
-void     eog_scroll_view_zoom_in          (EogScrollView *view, gboolean smooth);
-void     eog_scroll_view_zoom_out         (EogScrollView *view, gboolean smooth);
-void     eog_scroll_view_zoom_fit         (EogScrollView *view);
-void     eog_scroll_view_set_zoom         (EogScrollView *view, double zoom);
-double   eog_scroll_view_get_zoom         (EogScrollView *view);
-gboolean eog_scroll_view_get_zoom_is_min  (EogScrollView *view);
-gboolean eog_scroll_view_get_zoom_is_max  (EogScrollView *view);
-void     eog_scroll_view_show_cursor      (EogScrollView *view);
-void     eog_scroll_view_hide_cursor      (EogScrollView *view);
-
 G_END_DECLS
 
 #endif /* _EOG_SCROLL_VIEW_H_ */
Index: src/eog-view.h
===================================================================
--- src/eog-view.h	(revisión: 0)
+++ src/eog-view.h	(revisión: 0)
@@ -0,0 +1,137 @@
+/* Eye of GNOME -- Image Viewing Widget
+ *
+ * Copyright (C) 2008 The Free Software Foundation
+ *
+ * Author: Javier Sanchez  <jsanchez@deskblue.com>
+ *
+ * Based on code by:
+ *      - Lucas Rocha       <lucasr@gnome.org>
+ * 	- Claudio Saavedra  <csaavedra@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _EOG_VIEW_H
+#define _EOG_VIEW_H
+
+#include <gtk/gtk.h>
+#include "eog-image.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EogView        EogView;
+typedef struct _EogViewPrivate EogViewPrivate;
+typedef struct _EogViewClass   EogViewClass;
+
+#define EOG_TYPE_VIEW            (eog_view_get_type ())
+#define EOG_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), EOG_TYPE_VIEW, EogView))
+#define EOG_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  EOG_TYPE_VIEW, EogViewClass))
+#define EOG_IS_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EOG_TYPE_VIEW))
+#define EOG_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  EOG_TYPE_VIEW))
+#define EOG_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  EOG_TYPE_VIEW, EogViewClass))
+
+typedef enum {
+	EOG_TRANSP_BACKGROUND,
+	EOG_TRANSP_CHECKED,
+	EOG_TRANSP_COLOR
+} EogTransparencyStyle;
+
+struct _EogView {
+	GtkBin parent;
+
+	EogViewPrivate *priv;
+};
+
+struct _EogViewClass
+{
+	GtkBinClass parent_class;
+
+	/* -- virtual methods -- */
+	void     (* set_image)             (EogView *view,
+					    EogImage *image);
+
+	void     (* set_scroll_wheel_zoom) (EogView *view,
+					    gboolean scroll_wheel_zoom);
+
+	void     (* set_zoom_upscale)      (EogView *view,
+					    gboolean upscale);
+
+	void     (* set_zoom_multiplier)   (EogView *view,
+					    gdouble multiplier);
+  
+	void     (* set_antialiasing)      (EogView *view,
+					    gboolean state);
+
+	void     (* set_transparency)      (EogView *view,
+					    EogTransparencyStyle style,
+					    GdkColor *color);
+
+	gboolean (* scrollbars_visible)    (EogView *view);
+  
+	void	 (* set_popup)             (EogView *view,
+					    GtkMenu *menu);
+
+	void     (* set_bg_color)          (EogView *view,
+					    GdkColor *color);
+
+	void     (* zoom_in)               (EogView *view,
+					    gboolean smooth);
+
+	void     (* zoom_out)              (EogView *view,
+					    gboolean smooth);
+
+	void     (* zoom_fit)              (EogView *view);
+
+	void     (* set_zoom)              (EogView *view,
+					    double zoom);
+
+	double   (* get_zoom)              (EogView *view);
+
+	gboolean (* get_zoom_is_min)       (EogView *view);
+
+	gboolean (* get_zoom_is_max)       (EogView *view);
+
+	void     (* show_cursor)           (EogView *view);
+
+	void     (* hide_cursor)           (EogView *view);
+};
+
+GType      eog_view_get_type               (void) G_GNUC_CONST;
+
+/* --- Old API --- */
+void       eog_view_set_image              (EogView *view, EogImage *image);
+
+void       eog_view_set_scroll_wheel_zoom  (EogView *view, gboolean scroll_wheel_zoom);
+void       eog_view_set_zoom_upscale       (EogView *view, gboolean upscale);
+void       eog_view_set_zoom_multiplier    (EogView *view, gdouble multiplier);
+void       eog_view_set_antialiasing       (EogView *view, gboolean state);
+void       eog_view_set_transparency       (EogView *view, EogTransparencyStyle style, GdkColor *color);
+gboolean   eog_view_scrollbars_visible     (EogView *view);
+void	   eog_view_set_popup              (EogView *view, GtkMenu *menu);
+void	   eog_view_set_bg_color           (EogView *view, GdkColor *color);
+
+void       eog_view_zoom_in                (EogView *view, gboolean smooth);
+void       eog_view_zoom_out               (EogView *view, gboolean smooth);
+void       eog_view_zoom_fit               (EogView *view);
+void       eog_view_set_zoom               (EogView *view, double zoom);
+double     eog_view_get_zoom               (EogView *view);
+gboolean   eog_view_get_zoom_is_min        (EogView *view);
+gboolean   eog_view_get_zoom_is_max        (EogView *view);
+void       eog_view_show_cursor            (EogView *view);
+void       eog_view_hide_cursor            (EogView *view);
+
+G_END_DECLS
+
+#endif /* EOG_VIEW_H */
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revisión: 4685)
+++ src/Makefile.am	(copia de trabajo)
@@ -64,6 +64,7 @@
 	eog-transform.h			\
 	eog-image.h			\
 	eog-image-save-info.h		\
+	eog-view.h			\
 	eog-scroll-view.h		\
 	eog-thumb-view.h		\
 	eog-list-store.h		\
@@ -93,6 +94,7 @@
 	eog-image.c			\
 	eog-image-jpeg.c		\
 	eog-image-save-info.c		\
+	eog-view.c			\
 	eog-scroll-view.c		\
 	eog-thumb-view.c		\
 	eog-list-store.c		\
Index: bindings/python/eog.override
===================================================================
--- bindings/python/eog.override	(revisión: 4685)
+++ bindings/python/eog.override	(copia de trabajo)
@@ -14,6 +14,7 @@
 #include "eog-sidebar.h"
 #include "eog-thumb-nav.h"
 #include "eog-image.h"
+#include "eog-view.h"
 #include "eog-scroll-view.h"
 #include "eog-thumb-view.h"
 #include "eog-list-store.h"
@@ -59,7 +60,7 @@
 import gtk.ListStore as PyGtkListStore_Type
 import gtk.HBox as PyGtkHBox_Type
 import gtk.VBox as PyGtkVBox_Type
-import gtk.Table as PyGtkTable_Type
+import gtk.Bin as PyGtkBin_Type
 import gtk.IconView as PyGtkIconView_Type
 import gnomevfs.URI as PyGnomeVFSURI_Type
 %%
Index: bindings/python/eog.defs
===================================================================
--- bindings/python/eog.defs	(revisión: 4685)
+++ bindings/python/eog.defs	(copia de trabajo)
@@ -98,9 +98,16 @@
   (gtype-id "EOG_TYPE_PROPERTIES_DIALOG")
 )
 
+(define-object View
+  (in-module "Eog")
+  (parent "GtkBin")
+  (c-name "EogView")
+  (gtype-id "EOG_TYPE_VIEW")
+)
+
 (define-object ScrollView
   (in-module "Eog")
-  (parent "GtkTable")
+  (parent "EogView")
   (c-name "EogScrollView")
   (gtype-id "EOG_TYPE_SCROLL_VIEW")
 )
@@ -900,22 +907,23 @@
 
 
 
-;; From eog-scroll-view.h
 
-(define-function eog_scroll_view_get_type
-  (c-name "eog_scroll_view_get_type")
+;; From eog-view.h
+
+(define-function eog_view_get_type
+  (c-name "eog_view_get_type")
   (return-type "GType")
 )
 
-(define-function eog_scroll_view_new
-  (c-name "eog_scroll_view_new")
-  (is-constructor-of "EogScrollView")
+(define-function eog_view_new
+  (c-name "eog_view_new")
+  (is-constructor-of "EogView")
   (return-type "GtkWidget*")
 )
 
 (define-method set_image
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_set_image")
+  (of-object "EogView")
+  (c-name "eog_view_set_image")
   (return-type "none")
   (parameters
     '("EogImage*" "image")
@@ -923,8 +931,8 @@
 )
 
 (define-method set_zoom_upscale
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_set_zoom_upscale")
+  (of-object "EogView")
+  (c-name "eog_view_set_zoom_upscale")
   (return-type "none")
   (parameters
     '("gboolean" "upscale")
@@ -932,8 +940,8 @@
 )
 
 (define-method set_zoom_multiplier
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_set_zoom_multiplier")
+  (of-object "EogView")
+  (c-name "eog_view_set_zoom_multiplier")
   (return-type "none")
   (parameters
     '("gdouble" "multiplier")
@@ -941,8 +949,8 @@
 )
 
 (define-method set_antialiasing
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_set_antialiasing")
+  (of-object "EogView")
+  (c-name "eog_view_set_antialiasing")
   (return-type "none")
   (parameters
     '("gboolean" "state")
@@ -950,8 +958,8 @@
 )
 
 (define-method set_transparency
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_set_transparency")
+  (of-object "EogView")
+  (c-name "eog_view_set_transparency")
   (return-type "none")
   (parameters
     '("EogTransparencyStyle" "style")
@@ -960,14 +968,14 @@
 )
 
 (define-method scrollbars_visible
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_scrollbars_visible")
+  (of-object "EogView")
+  (c-name "eog_view_scrollbars_visible")
   (return-type "gboolean")
 )
 
 (define-method zoom_in
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_zoom_in")
+  (of-object "EogView")
+  (c-name "eog_view_zoom_in")
   (return-type "none")
   (parameters
     '("gboolean" "smooth")
@@ -975,8 +983,8 @@
 )
 
 (define-method zoom_out
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_zoom_out")
+  (of-object "EogView")
+  (c-name "eog_view_zoom_out")
   (return-type "none")
   (parameters
     '("gboolean" "smooth")
@@ -984,14 +992,14 @@
 )
 
 (define-method zoom_fit
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_zoom_fit")
+  (of-object "EogView")
+  (c-name "eog_view_zoom_fit")
   (return-type "none")
 )
 
 (define-method set_zoom
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_set_zoom")
+  (of-object "EogView")
+  (c-name "eog_view_set_zoom")
   (return-type "none")
   (parameters
     '("double" "zoom")
@@ -999,37 +1007,38 @@
 )
 
 (define-method get_zoom
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_get_zoom")
+  (of-object "EogView")
+  (c-name "eog_view_get_zoom")
   (return-type "double")
 )
 
 (define-method get_zoom_is_min
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_get_zoom_is_min")
+  (of-object "EogView")
+  (c-name "eog_view_get_zoom_is_min")
   (return-type "gboolean")
 )
 
 (define-method get_zoom_is_max
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_get_zoom_is_max")
+  (of-object "EogView")
+  (c-name "eog_view_get_zoom_is_max")
   (return-type "gboolean")
 )
 
 (define-method show_cursor
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_show_cursor")
+  (of-object "EogView")
+  (c-name "eog_view_show_cursor")
   (return-type "none")
 )
 
 (define-method hide_cursor
-  (of-object "EogScrollView")
-  (c-name "eog_scroll_view_hide_cursor")
+  (of-object "EogView")
+  (c-name "eog_view_hide_cursor")
   (return-type "none")
 )
 
 
 
+
 ;; From eog-sidebar.h
 
 (define-function eog_sidebar_get_type
