diff --git a/Common/Context.h b/Common/Context.h
index b7dea14908464370f06ddd9614e7c3a4ff6bf7dd..673da93afe1db36911ad11304d13b25ee31ccb03 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -199,6 +199,7 @@ public :
     int smooth, anim_cycle, combine_time, combine_remove_orig ;
     int file_format, plugins;
     double anim_delay ;
+    void (*plugin_draw_function)(void) ;
   }post;
 
   // solver options 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index bc56d956a93e2487876e437d454c9df6539336d7..c4a5aa073dde769a8b4fcfd60514a73b534b6eec 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.197 2004-10-28 08:13:09 geuzaine Exp $
+// $Id: Options.cpp,v 1.198 2004-10-30 03:07:29 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -137,6 +137,7 @@ void Init_Options(int num)
   CTX.mesh.oldxtrude = CTX.mesh.oldxtrude_recombine = 0;        //old extrusion mesh generator
   CTX.mesh.check_duplicates = 0;        //check for duplicate nodes in Read_Mesh
   CTX.post.combine_time = 0; // try to combine_time views at startup
+  CTX.post.plugin_draw_function = NULL;
 #if defined(HAVE_FLTK)
   CTX.gl_font_enum = FL_HELVETICA;
 #else
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index f66ef0fa4e60a97e98392cc5afa9eac01745a287..b4461b6fba9dd6fe5d3d192dc652c7e8f5d7c5c8 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.294 2004-10-28 06:57:34 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.295 2004-10-30 03:07:29 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -3379,6 +3379,13 @@ void view_plugin_run_cb(CALLBACK_ARGS)
   }
 }
 
+void view_plugin_input_cb(CALLBACK_ARGS)
+{
+  double (*f)(int, int, double) = (double (*)(int, int, double)) data;
+  Fl_Value_Input *input = (Fl_Value_Input*) w;
+  f(-1, 0, input->value());
+}
+
 void view_plugin_options_cb(CALLBACK_ARGS)
 {
   std::pair<int, GMSH_Plugin *> *pair = (std::pair<int, GMSH_Plugin *>*) data;
@@ -3390,6 +3397,22 @@ void view_plugin_options_cb(CALLBACK_ARGS)
 
   p->dialogBox->current_view_index = iView;
   p->dialogBox->run_button->callback(view_plugin_run_cb, (void *)p);
+
+  // configure the input fields (we get step, min and max by calling
+  // the option function with action==1, 2 and 3, respectively) and
+  // set the Fl_Value_Input callbacks
+  int n = p->getNbOptions();
+  if(n > 20) n = 20;
+  for(int i = 0; i < n; i++) {
+    StringXNumber *sxn = p->getOption(i);
+    if(sxn->function){
+      p->dialogBox->value[i]->callback(view_plugin_input_cb, (void*)sxn->function);
+      p->dialogBox->value[i]->step(sxn->function(iView, 1, 0.));
+      p->dialogBox->value[i]->minimum(sxn->function(iView, 2, 0.));
+      p->dialogBox->value[i]->maximum(sxn->function(iView, 3, 0.));
+    }
+  }
+
   p->dialogBox->main_window->show();
 }
 
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index e6a573983eb3e9952e763c71ddbf9a9aa32fd4b1..757e6f29f5eab50128822da77d4ba19c43977484 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.111 2004-10-15 18:36:04 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.112 2004-10-30 03:07:29 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -249,6 +249,11 @@ void Draw_Mesh(Mesh * M)
   if(CTX.axes)
     Draw_Axes(CTX.lc_middle / 4.);
 
+  // draw any plugin-specific stuff
+  
+  if(CTX.post.plugin_draw_function)
+    (*CTX.post.plugin_draw_function)();
+
   // draw the post-processing views
 
   Draw_Post();
diff --git a/Plugin/CutMap.cpp b/Plugin/CutMap.cpp
index f855fe514271b6419600df4d9f1e4ffbadb93b9e..e561141eefc16e68ec644e9ab5f096a38b74d362 100644
--- a/Plugin/CutMap.cpp
+++ b/Plugin/CutMap.cpp
@@ -1,4 +1,4 @@
-// $Id: CutMap.cpp,v 1.38 2004-09-16 19:15:27 geuzaine Exp $
+// $Id: CutMap.cpp,v 1.39 2004-10-30 03:07:29 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -26,7 +26,7 @@
 extern Context_T CTX;
 
 StringXNumber CutMapOptions_Number[] = {
-  {GMSH_FULLRC, "A", NULL, 1.},
+  {GMSH_FULLRC, "A", GMSH_CutMapPlugin::callbackA, 1.},
   {GMSH_FULLRC, "dTimeStep", NULL, -1.},
   {GMSH_FULLRC, "dView", NULL, -1.},
   {GMSH_FULLRC, "iView", NULL, -1.}
@@ -45,6 +45,25 @@ GMSH_CutMapPlugin::GMSH_CutMapPlugin()
   ;
 }
 
+double GMSH_CutMapPlugin::callbackA(int num, int action, double value)
+{
+  double min = 0., max = 1.;
+  if(action > 0){
+    Post_View *v = (Post_View*)List_Pointer_Test(CTX.post.list, num);
+    if(v){
+      min = v->Min;
+      max = v->Max;
+    }
+  }
+  switch(action){ // configure the input field
+  case 1: return (min-max)/200.;
+  case 2: return min;
+  case 3: return max;
+  default: break;
+  }
+  return 0.;
+}
+
 void GMSH_CutMapPlugin::getName(char *name) const
 {
   strcpy(name, "Cut map");
diff --git a/Plugin/CutMap.h b/Plugin/CutMap.h
index 48203342d6dbf74404cecb82c07699b889758a43..95efab52994bb9d797ef2689219137ef476e1dca 100644
--- a/Plugin/CutMap.h
+++ b/Plugin/CutMap.h
@@ -38,6 +38,8 @@ class GMSH_CutMapPlugin : public GMSH_LevelsetPlugin
   int getNbOptions() const;
   StringXNumber* getOption (int iopt);  
   Post_View *execute (Post_View *);
+
+  static double callbackA(int, int, double);
 };
 
 #endif
diff --git a/Plugin/CutPlane.cpp b/Plugin/CutPlane.cpp
index 3ed27f666d8b39c56f15b6490817cceace7b51e4..3d5b1a291b30e54b88cec42d692ccb9fe40d1b70 100644
--- a/Plugin/CutPlane.cpp
+++ b/Plugin/CutPlane.cpp
@@ -1,4 +1,4 @@
-// $Id: CutPlane.cpp,v 1.34 2004-05-16 20:04:43 geuzaine Exp $
+// $Id: CutPlane.cpp,v 1.35 2004-10-30 03:07:29 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -23,13 +23,20 @@
 #include "List.h"
 #include "Context.h"
 
+#if defined(HAVE_FLTK)
+#include "GmshUI.h"
+#include "Draw.h"
+#endif
+
 extern Context_T CTX;
 
+int GMSH_CutPlanePlugin::iview = 0;
+
 StringXNumber CutPlaneOptions_Number[] = {
-  {GMSH_FULLRC, "A", NULL, 1.},
-  {GMSH_FULLRC, "B", NULL, 0.},
-  {GMSH_FULLRC, "C", NULL, 0.},
-  {GMSH_FULLRC, "D", NULL, -0.01},
+  {GMSH_FULLRC, "A", GMSH_CutPlanePlugin::callbackA, 1.},
+  {GMSH_FULLRC, "B", GMSH_CutPlanePlugin::callbackB, 0.},
+  {GMSH_FULLRC, "C", GMSH_CutPlanePlugin::callbackC, 0.},
+  {GMSH_FULLRC, "D", GMSH_CutPlanePlugin::callbackD, -0.01},
   {GMSH_FULLRC, "iView", NULL, -1.}
 };
 
@@ -41,12 +48,100 @@ extern "C"
   }
 }
 
-
 GMSH_CutPlanePlugin::GMSH_CutPlanePlugin()
 {
   ;
 }
 
+void GMSH_CutPlanePlugin::draw()
+{
+#if defined(HAVE_FLTK)
+  Post_View *v = (Post_View*)List_Pointer_Test(CTX.post.list, iview);
+  if(!v) return;
+  Draw_PlaneInBoundingBox(v->BBox[0], v->BBox[2], v->BBox[4],
+			  v->BBox[1], v->BBox[3], v->BBox[5],
+			  CutPlaneOptions_Number[0].def,
+			  CutPlaneOptions_Number[1].def,
+			  CutPlaneOptions_Number[2].def,
+			  CutPlaneOptions_Number[3].def);
+#endif
+}
+
+void GMSH_CutPlanePlugin::callback()
+{
+#if defined(HAVE_FLTK)
+  CTX.post.plugin_draw_function = draw;
+  int old = CTX.draw_bbox;
+  CTX.draw_bbox = 1;
+  if(CTX.fast_redraw){
+    CTX.post.draw = 0;
+    CTX.mesh.draw = 0;
+  }
+  if(!CTX.batch) 
+    Draw();
+  CTX.post.plugin_draw_function = NULL;
+  CTX.draw_bbox = old;
+  CTX.post.draw = 1;
+  CTX.mesh.draw = 1;
+#endif
+}
+
+double GMSH_CutPlanePlugin::callbackA(int num, int action, double value)
+{
+  if(action > 0) iview = num;
+  switch(action){ // configure the input field
+  case 1: return 0.01;
+  case 2: return -1.;
+  case 3: return 1.;
+  default: break;
+  }
+  CutPlaneOptions_Number[0].def = value;
+  callback();
+  return 0.;
+}
+
+double GMSH_CutPlanePlugin::callbackB(int num, int action, double value)
+{
+  if(action > 0) iview = num;
+  switch(action){
+  case 1: return 0.01;
+  case 2: return -1.;
+  case 3: return 1.;
+  default: break;
+  }
+  CutPlaneOptions_Number[1].def = value;
+  callback();
+  return 0.;
+}
+
+double GMSH_CutPlanePlugin::callbackC(int num, int action, double value)
+{
+  if(action > 0) iview = num;
+  switch(action){
+  case 1: return 0.01;
+  case 2: return -1.;
+  case 3: return 1.;
+  default: break;
+  }
+  CutPlaneOptions_Number[2].def = value;
+  callback();
+  return 0.;
+}
+
+double GMSH_CutPlanePlugin::callbackD(int num, int action, double value)
+{
+  if(action > 0) iview = num;
+  switch(action){
+  case 1: return CTX.lc/200.;
+  case 2: return -CTX.lc;
+  case 3: return CTX.lc;
+  default: break;
+  }
+  CutPlaneOptions_Number[3].def = value;
+  callback();
+  return 0.;
+}
+
 void GMSH_CutPlanePlugin::getName(char *name) const
 {
   strcpy(name, "Cut plane");
diff --git a/Plugin/CutPlane.h b/Plugin/CutPlane.h
index 0aef83536595e0f486f42bfcacac97c1ec4ae551..434828345ae8b04a0352bfa532266fb6834b7fc2 100644
--- a/Plugin/CutPlane.h
+++ b/Plugin/CutPlane.h
@@ -30,6 +30,8 @@ extern "C"
 class GMSH_CutPlanePlugin : public GMSH_LevelsetPlugin
 {
   double levelset(double x, double y, double z, double val) const;
+  static void callback();
+  static int iview;
 public:
   GMSH_CutPlanePlugin();
   void getName(char *name) const;
@@ -38,6 +40,12 @@ public:
   int getNbOptions() const;
   StringXNumber *getOption(int iopt);  
   Post_View *execute(Post_View *);
+
+  static double callbackA(int, int, double);
+  static double callbackB(int, int, double);
+  static double callbackC(int, int, double);
+  static double callbackD(int, int, double);
+  static void draw();
 };
 
 #endif
diff --git a/Plugin/CutSphere.cpp b/Plugin/CutSphere.cpp
index 87ae2637dcb74a3fdb498c49408d8713a6fff0cb..f84866effdfb844fcd1cbe71ebd1423052975158 100644
--- a/Plugin/CutSphere.cpp
+++ b/Plugin/CutSphere.cpp
@@ -1,4 +1,4 @@
-// $Id: CutSphere.cpp,v 1.32 2004-05-16 20:04:43 geuzaine Exp $
+// $Id: CutSphere.cpp,v 1.33 2004-10-30 03:07:29 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -24,13 +24,18 @@
 #include "List.h"
 #include "Context.h"
 
+#if defined(HAVE_FLTK)
+#include "GmshUI.h"
+#include "Draw.h"
+#endif
+
 extern Context_T CTX;
 
 StringXNumber CutSphereOptions_Number[] = {
-  {GMSH_FULLRC, "Xc", NULL, 0.},
-  {GMSH_FULLRC, "Yc", NULL, 0.},
-  {GMSH_FULLRC, "Zc", NULL, 0.},
-  {GMSH_FULLRC, "R", NULL, 0.25},
+  {GMSH_FULLRC, "Xc", GMSH_CutSpherePlugin::callbackX, 0.},
+  {GMSH_FULLRC, "Yc", GMSH_CutSpherePlugin::callbackY, 0.},
+  {GMSH_FULLRC, "Zc", GMSH_CutSpherePlugin::callbackZ, 0.},
+  {GMSH_FULLRC, "R", GMSH_CutSpherePlugin::callbackR, 0.25},
   {GMSH_FULLRC, "iView", NULL, -1.}
 };
 
@@ -42,12 +47,101 @@ extern "C"
   }
 }
 
-
 GMSH_CutSpherePlugin::GMSH_CutSpherePlugin()
 {
   ;
 }
 
+void GMSH_CutSpherePlugin::draw()
+{
+#if defined(HAVE_FLTK)
+  static GLUquadricObj *qua;
+  static int first = 1;
+  if(first) {
+    first = 0;
+    qua = gluNewQuadric();
+  }
+  GLint mode[2];
+  glGetIntegerv(GL_POLYGON_MODE, mode);
+  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+  glPushMatrix();
+  glTranslated(CutSphereOptions_Number[0].def,
+	       CutSphereOptions_Number[1].def,
+	       CutSphereOptions_Number[2].def);
+  gluSphere(qua, CutSphereOptions_Number[3].def, 40, 40);
+  glPopMatrix();
+  glPolygonMode(GL_FRONT_AND_BACK, mode[1]);
+#endif
+}
+
+void GMSH_CutSpherePlugin::callback()
+{
+#if defined(HAVE_FLTK)
+  CTX.post.plugin_draw_function = draw;
+  if(CTX.fast_redraw){
+    CTX.post.draw = 0;
+    CTX.mesh.draw = 0;
+  }
+  if(!CTX.batch) 
+    Draw();
+  CTX.post.plugin_draw_function = NULL;
+  CTX.post.draw = 1;
+  CTX.mesh.draw = 1;
+#endif
+}
+
+double GMSH_CutSpherePlugin::callbackX(int num, int action, double value)
+{
+  switch(action){ // configure the input field
+  case 1: return CTX.lc/200.;
+  case 2: return -CTX.lc;
+  case 3: return CTX.lc;
+  default: break;
+  }
+  CutSphereOptions_Number[0].def = value;
+  callback();
+  return 0.;
+}
+
+double GMSH_CutSpherePlugin::callbackY(int num, int action, double value)
+{
+  switch(action){ // configure the input field
+  case 1: return CTX.lc/200.;
+  case 2: return -CTX.lc;
+  case 3: return CTX.lc;
+  default: break;
+  }
+  CutSphereOptions_Number[1].def = value;
+  callback();
+  return 0.;
+}
+
+double GMSH_CutSpherePlugin::callbackZ(int num, int action, double value)
+{
+  switch(action){ // configure the input field
+  case 1: return CTX.lc/200.;
+  case 2: return -CTX.lc;
+  case 3: return CTX.lc;
+  default: break;
+  }
+  CutSphereOptions_Number[2].def = value;
+  callback();
+  return 0.;
+}
+
+double GMSH_CutSpherePlugin::callbackR(int num, int action, double value)
+{
+  switch(action){
+  case 1: return CTX.lc/200.;
+  case 2: return 0.;
+  case 3: return 2*CTX.lc;
+  default: break;
+  }
+  CutSphereOptions_Number[3].def = value;
+  callback();
+  return 0.;
+}
+
 void GMSH_CutSpherePlugin::getName(char *name) const
 {
   strcpy(name, "Cut sphere");
diff --git a/Plugin/CutSphere.h b/Plugin/CutSphere.h
index d5891f89b9a57c955f6b7b018b0161893a611ae8..d4889b20d9be898789c4854d7b07826eeb8adc4e 100644
--- a/Plugin/CutSphere.h
+++ b/Plugin/CutSphere.h
@@ -30,6 +30,7 @@ extern "C"
 class GMSH_CutSpherePlugin : public GMSH_LevelsetPlugin
 {
   double levelset(double x, double y, double z, double val) const;
+  static void callback();
 public:
   GMSH_CutSpherePlugin();
   void getName(char *name) const;
@@ -38,6 +39,12 @@ public:
   int getNbOptions() const;
   StringXNumber* getOption(int iopt);  
   Post_View *execute(Post_View *);
+
+  static double callbackX(int, int, double);
+  static double callbackY(int, int, double);
+  static double callbackZ(int, int, double);
+  static double callbackR(int, int, double);
+  static void draw();
 };
 
 #endif
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 9d936656e0977070a9cfe8c50c7e57b3568881f6..e9c399672e4813008e1dc08baff6a7ff4861b238 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,12 +1,12 @@
-$Id: VERSIONS,v 1.262 2004-10-28 08:17:26 geuzaine Exp $
+$Id: VERSIONS,v 1.263 2004-10-30 03:07:29 geuzaine Exp $
 
 New since 1.56: generalized displacement maps to display arbitrary
 view types; the arrows representing a vector field can now also be
 colored by the values from other scalar, vector or tensor fields; new
 adaptive high order visualization mode; new options for solvers
 (SocketCommand and NameCommand) and views (ArrowSizeProportional);
-fixed display of undesired solver plugin popups; various small bug
-fixes and enhancements;
+fixed display of undesired solver plugin popups; enhanced interactive
+plugin behaviour; various small bug fixes and enhancements;
 
 New in 1.56: new post-processing option to draw a scalar view raised
 by a displacement view without using Plugin(DisplacementRaise) (makes