diff --git a/configure.ac b/configure.ac
index c7b95b0..bc6fff9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -285,6 +285,23 @@ fi
 AM_CONDITIONAL([HAVE_RSVG], [test "x$have_rsvg" = "xyes"])
 
 # ****************
+# utouch
+# ****************
+GRIP_REQUIRED=0.3.1
+
+AC_ARG_WITH([libgrip], AC_HELP_STRING([--without-libgrip], [disable libgrip support]))
+have_libgrip=no
+if test x$with_libgrip != xno; then
+   PKG_CHECK_MODULES(GRIP, libgrip >= $GRIP_REQUIRED, have_libgrip=yes, have_libgrip=no)
+fi
+if test "x$have_libgrip" = "xyes"; then
+  AC_DEFINE(HAVE_LIBGRIP, 1, [libgrip support])
+  EOG_MODULES="$EOG_MODULES libgrip >= $GRIP_REQUIRED"
+fi
+
+AM_CONDITIONAL([HAVE_LIBGRIP], [test "x$have_libgrip" = "xyes"])
+
+# ****************
 # CFLAGS/LIBS init
 # ****************
 
@@ -371,4 +388,5 @@ Configure summary:
 	JPEG support ...............:  ${have_jpeg}
 	Colour management support ..:  ${have_lcms}
 	GObject Introspection.......:  ${have_introspection}
+	Libgrip gestures............:  ${have_libgrip}
 "
diff --git a/src/eog-scroll-view.c b/src/eog-scroll-view.c
index f7542a5..bc59e3d 100644
--- a/src/eog-scroll-view.c
+++ b/src/eog-scroll-view.c
@@ -10,6 +10,9 @@
 #include <librsvg/rsvg.h>
 #include <librsvg/rsvg-cairo.h>
 #endif
+#ifdef HAVE_LIBGRIP
+#include <libgrip/grip.h>
+#endif
 
 #include "eog-config-keys.h"
 #include "eog-enum-types.h"
@@ -140,11 +143,17 @@ struct _EogScrollViewPrivate {
 	/* Scroll wheel zoom */
 	gdouble zoom_multiplier;
 
-	/* dragging stuff */
+	/* drag gesture data */
 	int drag_anchor_x, drag_anchor_y;
 	int drag_ofs_x, drag_ofs_y;
 	guint dragging : 1;
 
+#ifdef HAVE_LIBGRIP
+	/* pinch gesture data */
+	gdouble pinch_begin_radius;
+	gdouble pinch_begin_zoom;
+#endif
+
 #if 0
 	/* status of progressive loading */
 	ProgressiveState progressive_state;
@@ -1684,6 +1693,82 @@ eog_scroll_view_motion_event (GtkWidget *widget, GdkEventMotion *event, gpointer
 	return TRUE;
 }
 
+#ifdef HAVE_LIBGRIP
+static void
+gesture_event_cb (GtkWidget        *widget,
+                       GripTimeType      time_type,
+                       GripGestureEvent *event,
+                       gpointer          user_data)
+{
+        EogScrollView *view = EOG_SCROLL_VIEW (widget);
+        EogScrollViewPrivate *priv = view->priv;
+        GtkWindow *toplevel = (GtkWindow *)gtk_widget_get_toplevel (widget);
+
+
+        if (time_type == GRIP_TIME_START) {
+                switch (event->type) {
+                case GRIP_GESTURE_DRAG: {
+                        GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
+
+                        priv->dragging = TRUE;
+                        priv->drag_anchor_x = drag->position_x;
+                        priv->drag_anchor_y = drag->position_y;
+
+                        priv->drag_ofs_x = priv->xofs;
+                        priv->drag_ofs_y = priv->yofs;
+
+                        break;
+                }
+                case GRIP_GESTURE_PINCH: {
+                        GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
+
+                        priv->pinch_begin_radius = pinch->radius;
+                        priv->pinch_begin_zoom = priv->zoom;
+
+                        break;
+                }
+
+                default:
+                        break;
+                }
+        } else if (time_type == GRIP_TIME_END) {
+                switch (event->type) {
+                case GRIP_GESTURE_DRAG:
+                        priv->dragging = FALSE;
+                        break;
+
+                default:
+                        break;
+                }
+        } else {
+                switch (event->type) {
+                case GRIP_GESTURE_DRAG: {
+                        GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
+
+                        if (drag->fingers == 2) {
+                                drag_to (view, drag->position_x, drag->position_y);
+                        }
+
+                        break;
+                }
+
+                case GRIP_GESTURE_PINCH: {
+                        GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
+                        gdouble zoom_factor = pinch->radius / priv->pinch_begin_radius;
+
+                        set_zoom (view, priv->pinch_begin_zoom * zoom_factor,
+                                  TRUE, pinch->focus_x, pinch->focus_y);
+
+                        break;
+                }
+
+                default:
+                        break;
+                }
+        }
+}
+#endif
+
 static void
 display_map_event (GtkWidget *widget, GdkEvent *event, gpointer data)
 {
@@ -2460,6 +2545,29 @@ eog_scroll_view_init (EogScrollView *view)
 	priv->override_bg_color = NULL;
 	priv->background_surface = NULL;
 
+#ifdef HAVE_LIBGRIP
+	{
+	  GtkWidget *widget = GTK_WIDGET (view);
+	  GripGestureManager *manager = grip_gesture_manager_get ();
+
+	  grip_gesture_manager_register_window (manager,
+						widget,
+						GRIP_GESTURE_PINCH,
+						GRIP_DEVICE_ALL,
+						2,
+						gesture_event_cb,
+						NULL, NULL);
+
+	  grip_gesture_manager_register_window (manager,
+						widget,
+						GRIP_GESTURE_DRAG,
+						GRIP_DEVICE_TOUCHSCREEN,
+						2,
+						gesture_event_cb,
+						NULL, NULL);
+	}
+#endif
+
 	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),
diff --git a/src/eog-window.c b/src/eog-window.c
index 3a774a0..57bca09 100644
--- a/src/eog-window.c
+++ b/src/eog-window.c
@@ -68,6 +68,9 @@
 #include <gdk/gdkkeysyms.h>
 #include <gio/gdesktopappinfo.h>
 #include <gtk/gtk.h>
+#ifdef HAVE_LIBGRIP
+#include <libgrip/grip.h>
+#endif
 
 #include <libpeas/peas-extension-set.h>
 #include <libpeas/peas-activatable.h>
@@ -101,6 +104,10 @@ G_DEFINE_TYPE (EogWindow, eog_window, GTK_TYPE_WINDOW);
 
 #define EOG_WALLPAPER_FILENAME "eog-wallpaper"
 
+#ifdef HAVE_LIBGRIP
+#define EOG_GESTURE_ROTATE_THRESHOLD M_PI_4
+#endif
+
 #define is_rtl (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
 
 typedef enum {
@@ -190,6 +197,9 @@ struct _EogWindowPrivate {
 #ifdef HAVE_LCMS
         cmsHPROFILE         *display_profile;
 #endif
+#ifdef HAVE_LIBGRIP
+        gdouble              rotate_start_angle;
+#endif
 };
 
 static void eog_window_cmd_fullscreen (GtkAction *action, gpointer user_data);
@@ -4420,6 +4430,51 @@ eog_window_add_open_editor_action (EogWindow *window)
 	g_free (tooltip);
 }
 
+#ifdef HAVE_LIBGRIP
+static void
+window_gesture_event_cb (GtkWidget        *widget,
+                              GripTimeType      time_type,
+                              GripGestureEvent *event,
+                              gpointer          user_data)
+{
+	struct _EogWindowPrivate *priv = EOG_WINDOW(user_data)->priv;
+	if (time_type == GRIP_TIME_START) {
+		switch (event->type) {
+		case GRIP_GESTURE_ROTATE: {
+			GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
+			priv->rotate_start_angle = rotate->angle;
+			break;
+		}
+
+		default:
+			break;
+		}
+	}
+	if (time_type == GRIP_TIME_UPDATE) {
+		switch (event->type) {
+		case GRIP_GESTURE_ROTATE: {
+			GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
+
+			if (rotate->angle - priv->rotate_start_angle>= EOG_GESTURE_ROTATE_THRESHOLD) {
+				apply_transformation (EOG_WINDOW (user_data),
+						eog_transform_rotate_new (90));
+				priv->rotate_start_angle = rotate->angle;
+			} else if (priv->rotate_start_angle - rotate->angle >= EOG_GESTURE_ROTATE_THRESHOLD) {
+				apply_transformation (EOG_WINDOW (user_data),
+						eog_transform_rotate_new (270));
+				priv->rotate_start_angle = rotate->angle;
+			}
+
+			break;
+		}
+
+		default:
+			break;
+		}
+	}
+}
+#endif
+
 static void
 eog_window_construct_ui (EogWindow *window)
 {
@@ -4634,6 +4689,15 @@ eog_window_construct_ui (EogWindow *window)
 					     _eog_zoom_shrink_to_boolean,
 					     NULL, NULL, NULL);
 	}
+#ifdef HAVE_LIBGRIP
+	grip_gesture_manager_register_window (grip_gesture_manager_get (),
+					      priv->view,
+					      GRIP_GESTURE_ROTATE,
+					      GRIP_DEVICE_ALL,
+					      2,
+					      window_gesture_event_cb,
+					      window, NULL);
+#endif
 	g_settings_bind (priv->view_settings, EOG_CONF_VIEW_SCROLL_WHEEL_ZOOM,
 			 priv->view, "scrollwheel-zoom", G_SETTINGS_BIND_GET);
 	g_settings_bind (priv->view_settings, EOG_CONF_VIEW_ZOOM_MULTIPLIER,
