diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 35d7d5caa690e6f49fa8716f4d1ca00db9279b76..a9308e27ed93fa16cb6dcee3c5da54c0bd2bfbe3 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -680,8 +680,8 @@ StringXNumber GeneralOptions_Number[] = {
   { F|S, "VisibilityPositionY" , opt_general_visibility_position1 , 150. , 
     "Vertical position (in pixels) of the upper left corner of the visibility window" }, 
 
-  { F|O, "ZoomFactor" , opt_general_zoom_factor , 1.1 ,
-    "`Speed' of the middle mouse button zoom" },
+  { F|O, "ZoomFactor" , opt_general_zoom_factor , 4.0 ,
+    "Middle mouse button zoom acceleration factor" },
 
   { 0, NULL , NULL , 0. , NULL }
 } ;
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 267d918e1a989d721899998a69b5e516dede0910..d548ddb54cb0be4473190069230bd9aab61bfefd 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.212 2004-12-23 22:26:34 geuzaine Exp $
+// $Id: Options.cpp,v 1.213 2004-12-24 03:25:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -2639,6 +2639,10 @@ double opt_general_zoom_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
     CTX.zoom_factor = val;
+#if defined(HAVE_FLTK)
+  if(WID && (action & GMSH_GUI))
+    WID->gen_value[15]->value(CTX.zoom_factor);
+#endif
   return CTX.zoom_factor;
 }
 
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index d98b34982ce375828418a21b071115341248a09f..1637c4ff0b4d2d92bca57121b9213cd3f2e109ab 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.307 2004-12-23 03:21:36 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.308 2004-12-24 03:25:36 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -940,6 +940,7 @@ void general_options_ok_cb(CALLBACK_ARGS)
   opt_general_quadric_subdivisions(0, GMSH_SET, WID->gen_value[11]->value());
   opt_general_graphics_fontsize(0, GMSH_SET, WID->gen_value[12]->value());
   opt_general_clip_factor(0, GMSH_SET, WID->gen_value[14]->value());
+  opt_general_zoom_factor(0, GMSH_SET, WID->gen_value[15]->value());
 
   opt_general_default_filename(0, GMSH_SET, (char *)WID->gen_input[0]->value());
   opt_general_editor(0, GMSH_SET, (char *)WID->gen_input[1]->value());
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index c261ae68f649af7d7a80f655c86bb082e5c7341a..4d7ae559e6c7a62ecb737b9f9c282e9f3c985a8c 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.388 2004-12-23 03:19:58 geuzaine Exp $
+// $Id: GUI.cpp,v 1.389 2004-12-24 03:25:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1600,30 +1600,31 @@ void GUI::create_option_window()
       gen_butt[3]->down_box(TOGGLE_BOX);
       gen_butt[3]->selection_color(TOGGLE_COLOR);
 
-      gen_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Use fake transparency mode");
-      gen_butt[4]->type(FL_TOGGLE_BUTTON);
-      gen_butt[4]->down_box(TOGGLE_BOX);
-      gen_butt[4]->selection_color(TOGGLE_COLOR);
-
-      gen_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Use trackball rotation mode instead of Euler angles");
+      gen_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Use trackball rotation mode instead of Euler angles");
       gen_butt[5]->type(FL_TOGGLE_BUTTON);
       gen_butt[5]->down_box(TOGGLE_BOX);
       gen_butt[5]->selection_color(TOGGLE_COLOR);
 
-      gen_butt[15] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 9 * BH, BW, BH, "Rotate around pseudo center of mass");
+      gen_butt[15] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Rotate around pseudo center of mass");
       gen_butt[15]->type(FL_TOGGLE_BUTTON);
       gen_butt[15]->down_box(TOGGLE_BOX);
       gen_butt[15]->selection_color(TOGGLE_COLOR);
       gen_butt[15]->callback(general_options_rotation_center_cb);
 
-      gen_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 10 * BH, BB, BH, "Select");
+      gen_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 9 * BH, BB, BH, "Select");
       gen_push_butt[0]->callback(general_options_rotation_center_select_cb);
 
-      gen_value[8] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW / 3, BH);
-      gen_value[9] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 10 * BH, IW / 3, BH);
-      gen_value[10] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 10 * BH, IW / 3, BH, "Rotation center");
+      gen_value[8] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 3, BH);
+      gen_value[9] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 9 * BH, IW / 3, BH);
+      gen_value[10] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 9 * BH, IW / 3, BH, "Rotation center");
       gen_value[10]->align(FL_ALIGN_RIGHT);
 
+      gen_value[15] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Middle button zoom acceleration factor");
+      gen_value[15]->minimum(0.05);
+      gen_value[15]->maximum(20.);
+      gen_value[15]->step(0.05);
+      gen_value[15]->align(FL_ALIGN_RIGHT);
+
       o->end();
     }
     {
@@ -1699,13 +1700,18 @@ void GUI::create_option_window()
       gen_value[11]->step(1);
       gen_value[11]->align(FL_ALIGN_RIGHT);
 
-      gen_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Point size");
+      gen_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Use fake transparency mode");
+      gen_butt[4]->type(FL_TOGGLE_BUTTON);
+      gen_butt[4]->down_box(TOGGLE_BOX);
+      gen_butt[4]->selection_color(TOGGLE_COLOR);
+
+      gen_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Point size");
       gen_value[6]->minimum(0.1);
       gen_value[6]->maximum(50);
       gen_value[6]->step(0.1);
       gen_value[6]->align(FL_ALIGN_RIGHT);
 
-      gen_value[7] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
+      gen_value[7] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Line width");
       gen_value[7]->minimum(0.1);
       gen_value[7]->maximum(50);
       gen_value[7]->step(0.1);
@@ -1718,18 +1724,18 @@ void GUI::create_option_window()
 	{"3D arrow", 0, 0, 0},
 	{0}
       };
-      gen_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Vector display");
+      gen_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Vector display");
       gen_choice[0]->menu(menu_genvectype);
       gen_choice[0]->align(FL_ALIGN_RIGHT);
 
-      Fl_Button *b = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 6 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
+      Fl_Button *b = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 7 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
       b->callback(general_arrow_param_cb);
 
-      gen_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Font");
+      gen_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Font");
       gen_choice[1]->menu(menu_font_names);
       gen_choice[1]->align(FL_ALIGN_RIGHT);
 
-      gen_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Font size");
+      gen_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Font size");
       gen_value[12]->minimum(5);
       gen_value[12]->maximum(40);
       gen_value[12]->step(1);
diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp
index 0ec1ad4176e640c4c2187da3e6ea58c6a5f8a53e..de50b4add730922fb7e6f358705bc021726dfdca 100644
--- a/Fltk/Opengl_Window.cpp
+++ b/Fltk/Opengl_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl_Window.cpp,v 1.42 2004-11-15 20:15:33 geuzaine Exp $
+// $Id: Opengl_Window.cpp,v 1.43 2004-12-24 03:25:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -259,14 +259,13 @@ int Opengl_Window::handle(int event)
         }
       }
       else if(ibut == 2 || (ibut == 1 && Fl::event_state(FL_SHIFT))) {
-        if(!CTX.useTrackball)
-          set_r(2, CTX.r[2] + ((abs(ymov) > abs(xmov)) ? 
+	if(!CTX.useTrackball)
+          set_r(2, CTX.r[2] + (abs(ymov) > abs(xmov) ? 
 			       0 : -180 * (double)xmov / (double)w()));
-        set_s(0, CTX.s[0] * ((abs(ymov) > abs(xmov)) ? 
-			     ((ymov > 0) ? (double)(CTX.zoom_factor * (abs(ymov) + h())) /
-                              (double)h() : 
-			      (double)(h()) / (double)(CTX.zoom_factor * 
-						       (abs(ymov) + h()))) : 1.));
+	double zoomfact = (ymov > 0) ? 
+	  (double)(CTX.zoom_factor * abs(ymov) + h()) / (double)h() : 
+	  (double)(h()) / (double)(CTX.zoom_factor * abs(ymov) + h());
+	set_s(0, CTX.s[0] * (abs(ymov) > abs(xmov) ? zoomfact : 1.));
         set_s(1, CTX.s[0]);
         set_s(2, CTX.s[0]);
         if(abs(ymov) > abs(xmov)) {