diff --git a/modules/gui/src/gl_canvas.cc b/modules/gui/src/gl_canvas.cc
index d1714e803300fb63268865d83dc527d5079e7dfd..98f9ccc8444ba88568aef81449ab961d501e9a8f 100644
--- a/modules/gui/src/gl_canvas.cc
+++ b/modules/gui/src/gl_canvas.cc
@@ -39,6 +39,10 @@
 #include <QApplication>
 #include <QClipboard>
 #include <QMenu>
+
+#if QT_VERSION >= 0x040600
+# include <QGesture>
+#endif
 #include "tools/tool_manager.hh"
 
 namespace ost { namespace gui {
@@ -54,7 +58,8 @@ GLCanvas::GLCanvas(GLWin* gl_win,  QWidget* parent, const QGLFormat& f):
   bench_flag_(false),
   last_pos_(),
   scene_menu_(NULL),
-  show_beacon_(false)
+  show_beacon_(false),
+  angular_speed_(0.0)
 {
   if(!isValid()) return;
   master_timer_.start(10,this);
@@ -64,8 +69,52 @@ GLCanvas::GLCanvas(GLWin* gl_win,  QWidget* parent, const QGLFormat& f):
   this->setContextMenuPolicy(Qt::CustomContextMenu);
   connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this,
           SLOT(RequestContextMenu(const QPoint&)));
+#if QT_VERSION >= 0x040600
+  this->grabGesture(Qt::PinchGesture);
+#endif
+}
+
+bool GLCanvas::event(QEvent* event)
+{
+#if QT_VERSION >= 0x040600
+  if (event->type()==QEvent::Gesture) {
+    return this->GestureEvent(static_cast<QGestureEvent*>(event));
+  }
+#endif
+  return QGLWidget::event(event);
 }
 
+
+#if QT_VERSION >= 0x040600
+
+bool GLCanvas::GestureEvent(QGestureEvent* event)
+{
+  if (QGesture* pinch=event->gesture(Qt::PinchGesture)) {
+    QPinchGesture* pinch_gesture=static_cast<QPinchGesture*>(pinch);
+    QPinchGesture::ChangeFlags changeFlags = pinch_gesture->changeFlags();
+    if (changeFlags & QPinchGesture::RotationAngleChanged) {
+      qreal value=pinch_gesture->rotationAngle();
+      qreal lastValue=pinch_gesture->lastRotationAngle();
+      this->OnTransform(gfx::INPUT_COMMAND_ROTZ, 0, gfx::TRANSFORM_VIEW, 
+                  static_cast<Real>(value - lastValue));
+      this->update();
+      event->accept();
+      if (pinch_gesture->state()==Qt::GestureFinished) {
+        angular_speed_=value-lastValue;
+        if (!gesture_timer_.isActive())
+          gesture_timer_.start(10, this);
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+#endif
+
+
+
+
 void GLCanvas::MakeActive()
 {
   makeCurrent();
@@ -425,6 +474,22 @@ Real delta_time(const timeval& t1, const timeval& t2)
 void GLCanvas::timerEvent(QTimerEvent * event)
 {
 
+#if QT_VERSION>= 0x040600
+  // gesture support
+  if (gesture_timer_.timerId()==event->timerId()) {
+    if (angular_speed_!=0.0) {
+      angular_speed_*=0.95;
+      this->OnTransform(gfx::INPUT_COMMAND_ROTZ, 0, gfx::TRANSFORM_VIEW, 
+                        static_cast<Real>(angular_speed_));
+      if (std::abs(angular_speed_)<0.001) {
+        angular_speed_=0.0;
+        gesture_timer_.stop();
+      }
+      this->update();
+    }
+    return;
+  }
+#endif
 #ifndef _MSC_VER
   static struct timeval time0,time1;
   static int count=0;
diff --git a/modules/gui/src/gl_canvas.hh b/modules/gui/src/gl_canvas.hh
index 884588463fe49b9f5bd8346c29a8bcd871409178..db41234df1445d7cfda4de7f4dfc899cbcbd1970 100644
--- a/modules/gui/src/gl_canvas.hh
+++ b/modules/gui/src/gl_canvas.hh
@@ -83,11 +83,14 @@ protected:
   virtual void keyReleaseEvent(QKeyEvent* event);
   virtual void timerEvent(QTimerEvent * event);
   virtual void wheelEvent(QWheelEvent* event);
-
+  virtual bool event(QEvent* event);
 private slots:
   virtual void RequestContextMenu(const QPoint& pos);
 
 private:
+#if QT_VERSION >= 0x040600  
+  bool GestureEvent(QGestureEvent* event);
+#endif
   bool IsToolEvent(QInputEvent* event) const;
   MouseEvent::Buttons TranslateButtons(Qt::MouseButtons buttons) const;
   void HandleMousePressEvent(QMouseEvent* event);
@@ -103,6 +106,10 @@ private:
   QPoint last_pos_;
   SceneMenu* scene_menu_;
   bool show_beacon_;
+  float angular_speed_;
+#if QT_VERSION>=0x04600
+  QBasicTimer gesture_timer_;
+#endif
 };
 
 }} // ns