diff --git a/Common/Context.cpp b/Common/Context.cpp
index 65f6fa3fde53762d7c89cef511afaa55386b5f25..0cd885adeb28aa6de33740e489b9c7e69ed03630 100644
--- a/Common/Context.cpp
+++ b/Common/Context.cpp
@@ -1,4 +1,4 @@
-/* $Id: Context.cpp,v 1.11 2000-12-05 16:59:11 remacle Exp $ */
+/* $Id: Context.cpp,v 1.12 2000-12-05 18:38:08 geuzaine Exp $ */
 
 #include "Gmsh.h"
 #include "Const.h"
@@ -346,10 +346,6 @@ void Init_Context(void){
   // Default color options
   Init_Colors(0);
 
-  CTX.useTrackball = 1;
-  trackball(CTX.quaternion, 0.0, 0.0, 0.0, 0.0);  
-
-  //Print_Context(stdout);
 }
 
 void Print_Context(FILE *file){
@@ -396,20 +392,25 @@ void Print_Context(FILE *file){
 
 void Context_T::buildRotmatrix(float m[4][4])
 {
+  double r0, r1, r2;
+  extern void set_r(int i, double val);
+
   build_rotmatrix(m, quaternion);
 
-  r[1] = atan2(-m[0][2],sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]));
+  r1 = atan2(-m[0][2],sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]));
 
-  double c = cos(r[1]);  
+  double c = cos(r1);  
   if(c != 0.0)
     {
-      r[0] = atan2(m[1][2]/c,m[2][2]/c);
-      r[2] = atan2(-m[1][0]/c,m[0][0]/c);
-      r[0] *= 180./(Pi);
-      r[2] *= 180./(Pi);
+      r0 = atan2(m[1][2]/c,m[2][2]/c) ;
+      r2 = atan2(-m[1][0]/c,m[0][0]/c) ;
+      r0 *= 180./(Pi);
+      r2 *= 180./(Pi);
     }
   // lazyyyyyy
-  r[1] *= 180./(Pi);
+  set_r(0, r0);
+  set_r(1, r1 * 180./(Pi));
+  set_r(2, r2);
 }
 
 void Context_T::addQuaternion (float p1x, float p1y, float p2x, float p2y)
@@ -419,3 +420,7 @@ void Context_T::addQuaternion (float p1x, float p1y, float p2x, float p2y)
   add_quats(quat, quaternion, quaternion);  
 }
 
+void Context_T::setQuaternion (float p1x, float p1y, float p2x, float p2y)
+{
+  trackball(quaternion,p1x,p1y,p2x,p2y);
+}
diff --git a/Common/Context.h b/Common/Context.h
index f1ae9985c87fb04d6499d2c1aafa0651d190c7d5..206f936961f37c1d13933a339ea26db03ef189a0 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -1,4 +1,4 @@
-/* $Id: Context.h,v 1.12 2000-12-05 16:59:11 remacle Exp $ */
+/* $Id: Context.h,v 1.13 2000-12-05 18:38:08 geuzaine Exp $ */
 #ifndef _CONTEXT_H_
 #define _CONTEXT_H_
 
@@ -146,6 +146,7 @@ class Context_T {
 
   // trackball functions 
   void buildRotmatrix(float m[4][4]);
+  void setQuaternion (float p1x, float p1y, float p2x, float p2y);
   void addQuaternion (float p1x, float p1y, float p2x, float p2y);
 };
 
diff --git a/Common/Options.h b/Common/Options.h
index a4cf563332a8aed93bdc0bd2a2ff64525f7832a9..943eaacd3619e582425997af2eee856b3995f968 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -1,4 +1,4 @@
-/* $Id: Options.h,v 1.1 2000-12-05 15:28:22 geuzaine Exp $ */
+/* $Id: Options.h,v 1.2 2000-12-05 18:38:09 geuzaine Exp $ */
 #ifndef _OPTIONS_H_
 #define _OPTIONS_H_
 
@@ -56,6 +56,7 @@ StringXNumber GeneralOptions_Number[] = {
   { "SameVisual"   , GMSH_INT,    (void*)&CTX.same_visual   , 0. },
   { "Flash"        , GMSH_INT,    (void*)&CTX.flash         , 0. },
   { "AlphaBlending", GMSH_INT,    (void*)&CTX.alpha         , 0. },
+  { "Trackball"    , GMSH_INT,    (void*)&CTX.useTrackball  , 1. },
   { "Clip0"        , GMSH_INT,    (void*)&CTX.clip[0]       , 0. },
   { "Clip1"        , GMSH_INT,    (void*)&CTX.clip[1]       , 0. },
   { "Clip2"        , GMSH_INT,    (void*)&CTX.clip[2]       , 0. },
@@ -140,6 +141,8 @@ StringXNumber PrintOptions_Number[] = {
 // ARRAYS
 
 StringXArray GeneralOptions_Array[] = {
+  { "TrackballQuaternion" , 
+                       GMSH_FLOAT,  CTX.quaternion    , 0., 0., 0., 1. }, 
   { "ClipPlane0"     , GMSH_DOUBLE, CTX.clip_plane[0] , 0., 0., 0., 0. }, 
   { "ClipPlane1"     , GMSH_DOUBLE, CTX.clip_plane[1] , 0., 0., 0., 0. }, 
   { "ClipPlane2"     , GMSH_DOUBLE, CTX.clip_plane[2] , 0., 0., 0., 0. }, 
diff --git a/Unix/CbInput.cpp b/Unix/CbInput.cpp
index 95630d4d6397461fba2190a97ea88bfce8ff5a84..9267ff88ac1a8d55fd4e491bd38f3f27212981b0 100644
--- a/Unix/CbInput.cpp
+++ b/Unix/CbInput.cpp
@@ -1,4 +1,4 @@
-/* $Id: CbInput.cpp,v 1.9 2000-12-05 16:59:11 remacle Exp $ */
+/* $Id: CbInput.cpp,v 1.10 2000-12-05 18:38:11 geuzaine Exp $ */
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -455,7 +455,12 @@ void InputCb (Widget w, XtPointer client_data, GLwDrawingAreaCallbackStruct *cb)
     case 3:
       if(Modifier && !ZoomClick){
         Modifier = 0;
-        set_r(0,0.); set_r(1,0.); set_r(2,0.); 
+	if(CTX.useTrackball){
+	  CTX.setQuaternion(0.,0.,0.,0.);
+	}
+	else{
+	  set_r(0,0.); set_r(1,0.); set_r(2,0.); 
+	}
         set_t(0,0.); set_t(1,0.); set_t(2,0.);
         set_s(0,1.); set_s(1,1.); set_s(2,1.);
         Init();
diff --git a/Unix/CbOptions.cpp b/Unix/CbOptions.cpp
index 656ac7982ee068de359840b28abbd8eae35a1c0e..c80a12bd526daa1747b6f68830d6f2bbeee3934d 100644
--- a/Unix/CbOptions.cpp
+++ b/Unix/CbOptions.cpp
@@ -1,4 +1,4 @@
-/* $Id: CbOptions.cpp,v 1.9 2000-12-05 15:23:58 geuzaine Exp $ */
+/* $Id: CbOptions.cpp,v 1.10 2000-12-05 18:38:11 geuzaine Exp $ */
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -95,11 +95,29 @@ void OptionsCb (Widget w, XtPointer client_data, XtPointer call_data){
   case OPTIONS_SCALEX_LOCKED : CTX.slock[0] = !CTX.slock[0];  break;
   case OPTIONS_SCALEY_LOCKED : CTX.slock[1] = !CTX.slock[1];  break;
   case OPTIONS_SCALEZ_LOCKED : CTX.slock[2] = !CTX.slock[2];  break;
-  case OPTIONS_XVIEW : set_r(0,0.);  set_r(1,90.);set_r(2,0.); Init(); Draw(); break;
-  case OPTIONS_YVIEW : set_r(0,-90.);set_r(1,0.); set_r(2,0.); Init(); Draw(); break;
-  case OPTIONS_ZVIEW : set_r(0,0.);  set_r(1,0.); set_r(2,0.); Init(); Draw(); break;
-  case OPTIONS_CVIEW : set_t(0,0.);  set_t(1,0.); set_t(2,0.); 
-                       set_s(0,1.);  set_s(1,1.); set_s(2,1.); Init(); Draw(); break;
+  case OPTIONS_XVIEW : 
+    if(CTX.useTrackball)
+      CTX.setQuaternion(0.,0.,1.,0.);
+    set_r(0,0.);  set_r(1,90.);set_r(2,0.); 
+    Init(); Draw(); 
+    break;
+  case OPTIONS_YVIEW : 
+    if(CTX.useTrackball)
+      CTX.setQuaternion(0.,-1.,0.,0.);
+    set_r(0,-90.);set_r(1,0.); set_r(2,0.); 
+    Init(); Draw(); 
+    break;
+  case OPTIONS_ZVIEW :
+    if(CTX.useTrackball)
+      CTX.setQuaternion(0.,0.,0.,0.);
+    set_r(0,0.);  set_r(1,0.); set_r(2,0.); 
+    Init(); Draw(); 
+    break;
+  case OPTIONS_CVIEW : 
+    set_t(0,0.);  set_t(1,0.); set_t(2,0.); 
+    set_s(0,1.);  set_s(1,1.); set_s(2,1.); 
+    Init(); Draw(); 
+    break;
   case OPTIONS_PVIEW :
     XGetWindowAttributes(XtDisplay(WID.G.shell),XtWindow(WID.G.shell),&xattrib);
     fprintf(stderr, "-geometry %dx%d -viewport %g %g %g %g %g %g %g %g %g\n",
diff --git a/Unix/Main.cpp b/Unix/Main.cpp
index ddb8f1ff5f0e01127346a1c67cb6268086dae7f0..f4c9b77283bee0dfac021c94e10f99508854d6d1 100644
--- a/Unix/Main.cpp
+++ b/Unix/Main.cpp
@@ -1,4 +1,4 @@
-/* $Id: Main.cpp,v 1.17 2000-12-05 15:47:07 geuzaine Exp $ */
+/* $Id: Main.cpp,v 1.18 2000-12-05 18:38:11 geuzaine Exp $ */
 
 #include <signal.h>
 
@@ -61,6 +61,7 @@ char gmsh_help[]      =
   "  -nodb                 disable double buffering\n"
   "  -noov                 disable overlay visual\n"
   "  -alpha                enable alpha blending\n"
+  "  -notrack              use old interactive rotation mode\n"
   "  -geometry geom        specify main window geometry\n"
   "  -viewport 9*float     specify rotation, translation and scale\n"
   "  -display disp         specify display\n"
@@ -233,6 +234,9 @@ void Get_Options (int argc, char *argv[], int *nbfiles) {
       else if(!strcmp(argv[i]+1, "alpha")){ 
         CTX.alpha = 1; i++;
       }
+      else if(!strcmp(argv[i]+1, "notrack")){ 
+        CTX.useTrackball = 0; i++;
+      }
       else if(!strcmp(argv[i]+1, "flash")){ 
         CTX.flash = 1; i++;
       }