From 5bf95835b98b83823a1fa9e54d41e8b9bacb3160 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 26 Aug 2006 17:00:25 +0000
Subject: [PATCH] Options in the GUI are now applied instantenuously.

Please let me know if you see anything weird in the GUI.
---
 Common/Options.cpp       |    6 +-
 Fltk/Callbacks.cpp       | 4945 +++++++++++++++++++-------------------
 Fltk/Callbacks.h         |   19 +-
 Fltk/Colorbar_Window.cpp |   51 +-
 Fltk/GUI.cpp             |  379 ++-
 Fltk/GUI.h               |    1 +
 doc/VERSIONS             |    6 +-
 7 files changed, 2769 insertions(+), 2638 deletions(-)

diff --git a/Common/Options.cpp b/Common/Options.cpp
index 61a042f253..7e8a22e081 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.305 2006-08-26 13:34:44 geuzaine Exp $
+// $Id: Options.cpp,v 1.306 2006-08-26 17:00:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -2803,8 +2803,10 @@ double opt_general_fast_redraw(OPT_ARGS_NUM)
   if(action & GMSH_SET)
     CTX.fast_redraw = (int)val;
 #if defined(HAVE_FLTK)
-  if(WID && (action & GMSH_GUI))
+  if(WID && (action & GMSH_GUI)){
     WID->gen_butt[2]->value(CTX.fast_redraw);
+    activate_cb(NULL, (void*)"fast_redraw");
+  }
 #endif
   return CTX.fast_redraw;
 }
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index a12b756755..fd11e334d0 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.451 2006-08-26 13:34:44 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.452 2006-08-26 17:00:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -188,9 +188,17 @@ void activate_cb(CALLBACK_ARGS)
   // this is a central callback to activate/deactivate parts of the
   // GUI depending on the user's choices (or the option settings)
 
+  if(!data) return;
+
   char *str = (char*)data;
 
-  if(!strcmp(str, "rotation_center")){
+  if(!strcmp(str, "fast_redraw")){
+    if(WID->gen_butt[2]->value())
+      WID->opt_redraw->show();
+    else
+      WID->opt_redraw->hide();
+  }
+  else if(!strcmp(str, "rotation_center")){
     if(WID->gen_butt[15]->value()) {
       WID->gen_push_butt[0]->deactivate();
       WID->gen_value[8]->deactivate();
@@ -204,36 +212,6 @@ void activate_cb(CALLBACK_ARGS)
       WID->gen_value[10]->activate();
     }
   }
-  else if(!strcmp(str, "custom_range")){
-    if(WID->view_choice[7]->value() == 2){
-      WID->view_value[31]->activate();
-      WID->view_value[32]->activate();
-      WID->view_push_butt[1]->activate();
-      WID->view_push_butt[2]->activate();
-    }
-    else {
-      WID->view_value[31]->deactivate();
-      WID->view_value[32]->deactivate();
-      WID->view_push_butt[1]->deactivate();
-      WID->view_push_butt[2]->deactivate();
-    }
-  }
-  else if(!strcmp(str, "general_transform")){
-    if(WID->view_butt[6]->value()){
-      WID->view_choice[11]->activate();
-      WID->view_value[2]->activate();
-      WID->view_input[4]->activate();
-      WID->view_input[5]->activate();
-      WID->view_input[6]->activate();
-    }
-    else{
-      WID->view_choice[11]->deactivate();
-      WID->view_value[2]->deactivate();
-      WID->view_input[4]->deactivate();
-      WID->view_input[5]->deactivate();
-      WID->view_input[6]->deactivate();
-    }
-  }
   else if(!strcmp(str, "general_axes")){
     if(WID->gen_choice[4]->value()){
       WID->gen_value[17]->activate();
@@ -286,6 +264,36 @@ void activate_cb(CALLBACK_ARGS)
       WID->gen_value[27]->deactivate();
     }
   }
+  else if(!strcmp(str, "custom_range")){
+    if(WID->view_choice[7]->value() == 2){
+      WID->view_value[31]->activate();
+      WID->view_value[32]->activate();
+      WID->view_push_butt[1]->activate();
+      WID->view_push_butt[2]->activate();
+    }
+    else {
+      WID->view_value[31]->deactivate();
+      WID->view_value[32]->deactivate();
+      WID->view_push_butt[1]->deactivate();
+      WID->view_push_butt[2]->deactivate();
+    }
+  }
+  else if(!strcmp(str, "general_transform")){
+    if(WID->view_butt[6]->value()){
+      WID->view_choice[11]->activate();
+      WID->view_value[2]->activate();
+      WID->view_input[4]->activate();
+      WID->view_input[5]->activate();
+      WID->view_input[6]->activate();
+    }
+    else{
+      WID->view_choice[11]->deactivate();
+      WID->view_value[2]->deactivate();
+      WID->view_input[4]->deactivate();
+      WID->view_input[5]->deactivate();
+      WID->view_input[6]->deactivate();
+    }
+  }
   else if(!strcmp(str, "mesh_cut_plane")){
     if(WID->mesh_butt[16]->value()){
       WID->mesh_cut_plane->activate();
@@ -894,17 +902,6 @@ void options_restore_defaults_cb(CALLBACK_ARGS)
   Draw();
 }
 
-void options_ok_cb(CALLBACK_ARGS)
-{
-  general_options_ok_cb(w, data);
-  geometry_options_ok_cb(w, data);
-  mesh_options_ok_cb(w, data);
-  solver_options_ok_cb(w, data);
-  post_options_ok_cb(w, data);
-  view_options_ok_cb(w, (void *)WID->view_number);
-  Draw();
-}
-
 // General options
 
 void general_options_cb(CALLBACK_ARGS)
@@ -947,12 +944,11 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
   Msg(ONSCREEN, "");
 }
 
-void general_options_light_cb(CALLBACK_ARGS)
+void general_options_ok_cb(CALLBACK_ARGS)
 {
-  char *name = (char*)data;
-  double x, y, z;
-  static double lc = 0.;
+  activate_cb(NULL, data);
 
+  static double lc = 0.;
   if(lc != CTX.lc){
     lc = CTX.lc;
     for(int i = 2; i < 5; i++){
@@ -960,30 +956,24 @@ void general_options_light_cb(CALLBACK_ARGS)
       WID->gen_value[i]->maximum(5*CTX.lc);
     }
   }
-
-  if(!strcmp(name, "x") || !strcmp(name, "y") || !strcmp(name, "z")){
-    x = WID->gen_value[2]->value();
-    y = WID->gen_value[3]->value();
-    z = WID->gen_value[4]->value();
-    WID->gen_sphere->setValue(x, y, z);    
-  }
-  else if(!strcmp(name, "xyz")){
-    WID->gen_sphere->getValue(x, y, z);
-    WID->gen_value[2]->value(x);
-    WID->gen_value[3]->value(y);
-    WID->gen_value[4]->value(z);
+  if(data){
+    char *name = (char*)data;
+    if(!strcmp(name, "light_value")){
+      double x, y, z;
+      x = WID->gen_value[2]->value();
+      y = WID->gen_value[3]->value();
+      z = WID->gen_value[4]->value();
+      WID->gen_sphere->setValue(x, y, z);    
+    }
+    else if(!strcmp(name, "light_sphere")){
+      double x, y, z;
+      WID->gen_sphere->getValue(x, y, z);
+      WID->gen_value[2]->value(x);
+      WID->gen_value[3]->value(y);
+      WID->gen_value[4]->value(z);
+    }
   }
-  opt_general_shine(0, GMSH_SET, WID->gen_value[1]->value());
-  opt_general_shine_exponent(0, GMSH_SET, WID->gen_value[0]->value());
-  opt_general_light00(0, GMSH_SET, WID->gen_value[2]->value());
-  opt_general_light01(0, GMSH_SET, WID->gen_value[3]->value());
-  opt_general_light02(0, GMSH_SET, WID->gen_value[4]->value());
-  opt_general_light03(0, GMSH_SET, WID->gen_value[13]->value());
-  Draw();
-}
 
-void general_options_ok_cb(CALLBACK_ARGS)
-{
   opt_general_axes_auto_position(0, GMSH_SET, WID->gen_butt[0]->value());
   opt_general_small_axes(0, GMSH_SET, WID->gen_butt[1]->value());
   opt_general_fast_redraw(0, GMSH_SET, WID->gen_butt[2]->value());
@@ -1002,7 +992,13 @@ void general_options_ok_cb(CALLBACK_ARGS)
   opt_general_rotation_center_cg(0, GMSH_SET, WID->gen_butt[15]->value());
   opt_general_draw_bounding_box(0, GMSH_SET, WID->gen_butt[6]->value());
   opt_general_polygon_offset_always(0, GMSH_SET, WID->gen_butt[4]->value());
-  
+
+  opt_general_shine_exponent(0, GMSH_SET, WID->gen_value[0]->value());  
+  opt_general_shine(0, GMSH_SET, WID->gen_value[1]->value());
+  opt_general_light00(0, GMSH_SET, WID->gen_value[2]->value());
+  opt_general_light01(0, GMSH_SET, WID->gen_value[3]->value());
+  opt_general_light02(0, GMSH_SET, WID->gen_value[4]->value());
+  opt_general_light03(0, GMSH_SET, WID->gen_value[13]->value());
   opt_general_verbosity(0, GMSH_SET, WID->gen_value[5]->value());
   opt_general_point_size(0, GMSH_SET, WID->gen_value[6]->value());
   opt_general_line_width(0, GMSH_SET, WID->gen_value[7]->value());
@@ -1038,24 +1034,21 @@ void general_options_ok_cb(CALLBACK_ARGS)
 
   int val;
   switch (WID->gen_choice[0]->value()) {
-  case 0:
-    val = DRAW_POST_SEGMENT;
-    break;
-  case 1:
-    val = DRAW_POST_ARROW;
-    break;
-  case 2:
-    val = DRAW_POST_PYRAMID;
-    break;
-  default:
-    val = DRAW_POST_ARROW3D;
-    break;
+  case 0: val = DRAW_POST_SEGMENT; break;
+  case 1: val = DRAW_POST_ARROW; break;
+  case 2: val = DRAW_POST_PYRAMID; break;
+  default: val = DRAW_POST_ARROW3D; break;
   }
   opt_general_vector_type(0, GMSH_SET, val);
   opt_general_graphics_font(0, GMSH_SET, (char *)WID->gen_choice[1]->text());
   opt_general_orthographic(0, GMSH_SET, !WID->gen_choice[2]->value());
   opt_general_axes(0, GMSH_SET, WID->gen_choice[4]->value());
   opt_general_background_gradient(0, GMSH_SET, WID->gen_choice[5]->value());
+
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
+  Draw();
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
 void general_arrow_param_cb(CALLBACK_ARGS)
@@ -1080,6 +1073,8 @@ void geometry_options_cb(CALLBACK_ARGS)
 
 void geometry_options_ok_cb(CALLBACK_ARGS)
 {
+  activate_cb(NULL, data);
+
   opt_geometry_points(0, GMSH_SET, WID->geo_butt[0]->value());
   opt_geometry_lines(0, GMSH_SET, WID->geo_butt[1]->value());
   opt_geometry_surfaces(0, GMSH_SET, WID->geo_butt[2]->value());
@@ -1100,6 +1095,11 @@ void geometry_options_ok_cb(CALLBACK_ARGS)
 
   opt_geometry_point_type(0, GMSH_SET, WID->geo_choice[0]->value());
   opt_geometry_line_type(0, GMSH_SET, WID->geo_choice[1]->value());
+
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
+  Draw();
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
 // Mesh options
@@ -1111,6 +1111,18 @@ void mesh_options_cb(CALLBACK_ARGS)
 
 void mesh_options_ok_cb(CALLBACK_ARGS)
 {
+  activate_cb(NULL, data);
+
+  if(data){
+    char *name = (char*)data;
+    if(!strcmp(name, "cut_plane_invert")){
+      WID->mesh_value[14]->value(-WID->mesh_value[14]->value());
+      WID->mesh_value[15]->value(-WID->mesh_value[15]->value());
+      WID->mesh_value[16]->value(-WID->mesh_value[16]->value());
+      WID->mesh_value[17]->value(-WID->mesh_value[17]->value());
+    }
+  }
+
   opt_mesh_optimize(0, GMSH_SET, WID->mesh_butt[2]->value());
   opt_mesh_order(0, GMSH_SET, WID->mesh_butt[3]->value()? 2 : 1);
   opt_mesh_constrained_bgmesh(0, GMSH_SET, WID->mesh_butt[5]->value());
@@ -1181,39 +1193,11 @@ void mesh_options_ok_cb(CALLBACK_ARGS)
   opt_mesh_color_carousel(0, GMSH_SET, WID->mesh_choice[4]->value());
   opt_mesh_quality_type(0, GMSH_SET, WID->mesh_choice[6]->value());
   opt_mesh_label_type(0, GMSH_SET, WID->mesh_choice[7]->value());
-}
-
-void mesh_cut_plane_cb(CALLBACK_ARGS)
-{
-  if(!CTX.mesh.use_cut_plane)
-    return;
-
-  int old = CTX.draw_bbox;
-  CTX.draw_bbox = 1;
-  if(CTX.fast_redraw){
-    CTX.post.draw = 0;
-    CTX.mesh.draw = 0;
-  }
-
-  opt_mesh_cut_planea(0, GMSH_SET, WID->mesh_value[14]->value());
-  opt_mesh_cut_planeb(0, GMSH_SET, WID->mesh_value[15]->value());
-  opt_mesh_cut_planec(0, GMSH_SET, WID->mesh_value[16]->value());
-  opt_mesh_cut_planed(0, GMSH_SET, WID->mesh_value[17]->value());
 
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
   Draw();
-
-  CTX.draw_bbox = old;
-  CTX.post.draw = 1;
-  CTX.mesh.draw = 1;
-}
-
-void mesh_cut_plane_invert_cb(CALLBACK_ARGS)
-{
-  WID->mesh_value[14]->value(-WID->mesh_value[14]->value());
-  WID->mesh_value[15]->value(-WID->mesh_value[15]->value());
-  WID->mesh_value[16]->value(-WID->mesh_value[16]->value());
-  WID->mesh_value[17]->value(-WID->mesh_value[17]->value());
-  mesh_cut_plane_cb(NULL, NULL);
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
 // Solver options
@@ -1225,6 +1209,8 @@ void solver_options_cb(CALLBACK_ARGS)
 
 void solver_options_ok_cb(CALLBACK_ARGS)
 {
+  activate_cb(NULL, data);
+
   int old_listen = (int)opt_solver_listen(0, GMSH_GET, WID->solver_butt[0]->value());
   opt_solver_listen(0, GMSH_SET, WID->solver_butt[0]->value());
   if(!old_listen && WID->solver_butt[0]->value())
@@ -1233,6 +1219,11 @@ void solver_options_ok_cb(CALLBACK_ARGS)
   opt_solver_max_delay(0, GMSH_SET, WID->solver_value[0]->value());
 
   opt_solver_socket_name(0, GMSH_SET, (char *)WID->solver_input[0]->value());
+
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
+  Draw();
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
 // Post options
@@ -1244,6 +1235,8 @@ void post_options_cb(CALLBACK_ARGS)
 
 void post_options_ok_cb(CALLBACK_ARGS)
 {
+  activate_cb(NULL, data);
+
   opt_post_anim_cycle(0, GMSH_SET, WID->post_butt[0]->value());
   opt_post_combine_remove_orig(0, GMSH_SET, WID->post_butt[1]->value());
   opt_post_horizontal_scales(0, GMSH_SET, WID->post_butt[2]->value());
@@ -1251,1680 +1244,1462 @@ void post_options_ok_cb(CALLBACK_ARGS)
   opt_post_anim_delay(0, GMSH_SET, WID->post_value[0]->value());
 
   opt_post_link(0, GMSH_SET, WID->post_choice[0]->value());
-}
-
-// Statistics Menu
-
-void statistics_cb(CALLBACK_ARGS)
-{
-  WID->create_statistics_window();
-}
-
-void statistics_update_cb(CALLBACK_ARGS)
-{
-  WID->set_statistics(true);
-}
 
-void statistics_histogram_cb(CALLBACK_ARGS)
-{
-  char *name = (char*)data;
-  int type;
-  if(!strcmp(name, "Gamma"))
-    type = 0;
-  else if(!strcmp(name, "Eta"))
-    type = 1;
-  else
-    type = 2;
-  Create2DGraph(name, "# Elements", 100, 0, WID->quality[type]);
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
   Draw();
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
-// Messages Menu
+// View options
 
-void message_cb(CALLBACK_ARGS)
+void view_options_cb(CALLBACK_ARGS)
 {
-  WID->create_message_window();
+  WID->create_view_options_window((int)(long)data);
 }
 
-void message_copy_cb(CALLBACK_ARGS)
+void view_options_timestep_cb(CALLBACK_ARGS)
 {
-#define BUFFL 50000
-  static char buff[BUFFL];
-  strcpy(buff, "");
-  for(int i = 1; i <= WID->msg_browser->size(); i++) {
-    if(WID->msg_browser->selected(i)) {
-      const char *c = WID->msg_browser->text(i);
-      if(strlen(buff) + strlen(c) > BUFFL - 2) {
-        Msg(GERROR, "Text selection too large to copy");
-        break;
-      }
-      if(c[0] == '@')
-        strcat(buff, &c[5]);
-      else
-        strcat(buff, c);
-      strcat(buff, "\n");
+  int links = (int)opt_post_link(0, GMSH_GET, 0);
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
+    if((links == 2 || links == 4) ||
+       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
+       (links == 0 && i == WID->view_number)) {
+      opt_view_timestep(i, GMSH_SET, ((Fl_Value_Input *) w)->value());
     }
   }
-  // bof bof bof
-  Fl::copy(buff, strlen(buff), 0);
-  Fl::copy(buff, strlen(buff), 1);
+  Draw();
 }
 
-void message_clear_cb(CALLBACK_ARGS)
+void view_options_timestep_decr_cb(CALLBACK_ARGS)
 {
-  WID->msg_browser->clear();
+  int links = (int)opt_post_link(0, GMSH_GET, 0);
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
+    if((links == 2 || links == 4) ||
+       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
+       (links == 0 && i == WID->view_number)) {
+      opt_view_timestep(i, GMSH_SET | GMSH_GUI,
+                        opt_view_timestep(i, GMSH_GET, 0) - 1);
+    }
+  }
+  Draw();
 }
 
-void message_save_cb(CALLBACK_ARGS)
+void view_options_timestep_incr_cb(CALLBACK_ARGS)
 {
- test:
-  if(file_chooser(0, 1, "Save", "*")) {
-    char *name = file_chooser_get_name(1);
-    if(CTX.confirm_overwrite) {
-      if(!StatFile(name))
-        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", 
-		      "Cancel", "Replace", NULL, name))
-          goto test;
+  int links = (int)opt_post_link(0, GMSH_GET, 0);
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
+    if((links == 2 || links == 4) ||
+       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
+       (links == 0 && i == WID->view_number)) {
+      opt_view_timestep(i, GMSH_SET | GMSH_GUI,
+                        opt_view_timestep(i, GMSH_GET, 0) + 1);
     }
-    WID->save_message(name);
   }
+  Draw();
 }
 
-// Visibility Menu
-
-void visibility_cb(CALLBACK_ARGS)
+void view_arrow_param_cb(CALLBACK_ARGS)
 {
-  // get the visibility info from the model, and update the browser accordingly
-  WID->create_visibility_window();
-  WID->vis_browser->clear();
-  VisibilityManager::instance()->update(WID->vis_type->value());
-  for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){
-    WID->vis_browser->add(VisibilityManager::instance()->getBrowserLine(i).c_str());
-    if(VisibilityManager::instance()->getVisibility(i))
-      WID->vis_browser->select(i + 1);
+  double a = opt_view_arrow_head_radius(WID->view_number, GMSH_GET, 0);
+  double b = opt_view_arrow_stem_length(WID->view_number, GMSH_GET, 0);
+  double c = opt_view_arrow_stem_radius(WID->view_number, GMSH_GET, 0);
+  while(arrow_editor("Arrow Editor", a, b, c)){
+    opt_view_arrow_head_radius(WID->view_number, GMSH_SET, a);
+    opt_view_arrow_stem_length(WID->view_number, GMSH_SET, b);
+    opt_view_arrow_stem_radius(WID->view_number, GMSH_SET, c);
+    Draw();
   }
-  // active the delete button for physicals and partitions only!
-  if(WID->vis_type->value() == 1 || WID->vis_type->value() == 2)
-    WID->vis_push_butt[0]->activate();
-  else
-    WID->vis_push_butt[0]->deactivate();
 }
 
-void visibility_ok_cb(CALLBACK_ARGS)
+void view_options_ok_cb(CALLBACK_ARGS)
 {
-  // if the browser is not empty, get the selections made in the
-  // browser and apply them into the model
-  if(VisibilityManager::instance()->getNumEntities()){
-    CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
-    VisibilityManager::instance()->setAllInvisible(WID->vis_type->value());
-    for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++)
-      if(WID->vis_browser->selected(i + 1))
-	VisibilityManager::instance()->setVisibility(i, true, WID->vis_butt[0]->value());
-    // then refresh the browser to account for recursive selections
-    for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++)
-      if(VisibilityManager::instance()->getVisibility(i))
-	WID->vis_browser->select(i + 1);
-    Draw();
-  }
-}
-
-void visibility_save_cb(CALLBACK_ARGS)
-{
-  visibility_ok_cb(NULL, NULL);
-  std::string str = VisibilityManager::instance()->getStringForGEO();
-  add_infile((char*)str.c_str(), CTX.filename);
-}
+  int current = WID->view_number;
 
-void visibility_delete_cb(CALLBACK_ARGS)
-{
-  if(WID->vis_type->value() == 1)
-    GMODEL->deletePhysicalGroups();
-  else if(WID->vis_type->value() == 2)
-    GMODEL->deleteMeshPartitions();
-  visibility_cb(NULL, NULL);
-}
+  if(current < 0)
+    return;
 
-void visibility_sort_cb(CALLBACK_ARGS)
-{
-  char *str = (char*)data;
-  int val;
-  if(!strcmp(str, "type"))
-    val = 1;
-  else if(!strcmp(str, "number"))
-    val = 2;
-  else if(!strcmp(str, "name"))
-    val = 3;
-  else if(!strcmp(str, "-"))
-    val = -1;
-  else if(!strcmp(str, "+"))
-    val = -2;
-  else
-    val = 0;
+  activate_cb(NULL, data);
 
-  if(val == 0) { // select or deselect everything
-    int selectall = 0;
-    for(int i = 0; i < WID->vis_browser->size(); i++)
-      if(!WID->vis_browser->selected(i + 1)) {
-        selectall = 1;
-        break;
-      }
-    if(selectall)
-      for(int i = 0; i < WID->vis_browser->size(); i++)
-        WID->vis_browser->select(i + 1);
-    else
-      WID->vis_browser->deselect();
-  }
-  else if(val == -1){ // invert the selection
-    int *state = new int[WID->vis_browser->size()];
-    for(int i = 0; i < WID->vis_browser->size(); i++)
-      state[i] = WID->vis_browser->selected(i + 1);
-    WID->vis_browser->deselect();
-    for(int i = 0; i < WID->vis_browser->size(); i++)
-      if(!state[i]) WID->vis_browser->select(i + 1);
-    delete [] state;
-  }
-  else if(val == -2){ // create new parameter name for selection
-    for(int i = 0; i < WID->vis_browser->size(); i++){
-      if(WID->vis_browser->selected(i + 1)){
-	static char tmpstr[256];
-	sprintf(tmpstr, "%d", VisibilityManager::instance()->getTag(i));
-	WID->context_geometry_input[1]->value(tmpstr);
-	break;
-      }
+  if(data){
+    char *str = (char*)data;
+    if(!strcmp(str, "range_min")){
+      WID->view_value[31]->value(opt_view_min(WID->view_number, GMSH_GET, 0));
+    }
+    else if(!strcmp(str, "range_max")){
+      WID->view_value[32]->value(opt_view_max(WID->view_number, GMSH_GET, 0));
     }
-    WID->context_geometry_input[0]->value("NewName");
-    WID->create_geometry_context_window(0);
-  }
-  else { // set new sorting mode
-    VisibilityManager::instance()->setSortMode(val);
-    visibility_cb(NULL, NULL);
-  }
-}
-
-void visibility_number_cb(CALLBACK_ARGS)
-{
-  CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
-
-  int type = (int)(long)data;
-  bool val;
-  if(type >= 100){ // show
-    val = true;
-    type -= 100;
-  }
-  else{ // hide
-    val = false;
   }
   
-  char *str = (char *)WID->vis_input[type]->value();  
-  int all = !strcmp(str, "all") || !strcmp(str, "*");
-  int num = all ? 0 : atoi(str); 
-  VisibilityManager::instance()->setVisibilityByNumber(type, num, all, val);
-  int pos = WID->vis_browser->position();
-  visibility_cb(NULL, NULL);
-  WID->vis_browser->position(pos);
-  Draw();
-}
+  int force = 0, links = (int)opt_post_link(0, GMSH_GET, 0);
 
-// Clipping planes menu
+  // get the old values for the current view
 
-void clip_cb(CALLBACK_ARGS)
-{
-  WID->create_clip_window();
-}
+  double scale_type = opt_view_scale_type(current, GMSH_GET, 0);
+  double intervals_type = opt_view_intervals_type(current, GMSH_GET, 0);
+  double point_type = opt_view_point_type(current, GMSH_GET, 0);
+  double line_type = opt_view_line_type(current, GMSH_GET, 0);
+  double vector_type = opt_view_vector_type(current, GMSH_GET, 0);
+  double glyph_location = opt_view_glyph_location(current, GMSH_GET, 0);
+  double tensor_type = opt_view_tensor_type(current, GMSH_GET, 0);
+  double range_type = opt_view_range_type(current, GMSH_GET, 0);
+  double axes = opt_view_axes(current, GMSH_GET, 0);
+  double boundary = opt_view_boundary(current, GMSH_GET, 0);
+  double external_view = opt_view_external_view(current, GMSH_GET, 0);
+  double gen_raise_view = opt_view_gen_raise_view(current, GMSH_GET, 0);
+  double show_time = opt_view_show_time(current, GMSH_GET, 0);
 
-void clip_num_cb(CALLBACK_ARGS)
-{
-  WID->reset_clip_browser();
-}
+  double type = opt_view_type(current, GMSH_GET, 0);
+  double saturate_values = opt_view_saturate_values(current, GMSH_GET, 0);
+  double max_recursion_level = opt_view_max_recursion_level(current, GMSH_GET, 0);
+  double target_error = opt_view_target_error(current, GMSH_GET, 0);
+  double show_element = opt_view_show_element(current, GMSH_GET, 0);
+  double show_scale = opt_view_show_scale(current, GMSH_GET, 0);
+  double auto_position = opt_view_auto_position(current, GMSH_GET, 0);
+  double axes_auto_position = opt_view_axes_auto_position(current, GMSH_GET, 0);
+  double draw_strings = opt_view_draw_strings(current, GMSH_GET, 0);
+  double light = opt_view_light(current, GMSH_GET, 0);
+  double light_two_side = opt_view_light_two_side(current, GMSH_GET, 0);
+  double light_lines = opt_view_light_lines(current, GMSH_GET, 0);
+  double smooth_normals = opt_view_smooth_normals(current, GMSH_GET, 0);
+  double draw_points = opt_view_draw_points(current, GMSH_GET, 0);
+  double draw_lines = opt_view_draw_lines(current, GMSH_GET, 0);
+  double draw_triangles = opt_view_draw_triangles(current, GMSH_GET, 0);
+  double draw_quadrangles = opt_view_draw_quadrangles(current, GMSH_GET, 0);
+  double draw_tetrahedra = opt_view_draw_tetrahedra(current, GMSH_GET, 0);
+  double draw_hexahedra = opt_view_draw_hexahedra(current, GMSH_GET, 0);
+  double draw_prisms = opt_view_draw_prisms(current, GMSH_GET, 0);
+  double draw_pyramids = opt_view_draw_pyramids(current, GMSH_GET, 0);
+  double draw_scalars = opt_view_draw_scalars(current, GMSH_GET, 0);
+  double draw_vectors = opt_view_draw_vectors(current, GMSH_GET, 0);
+  double draw_tensors = opt_view_draw_tensors(current, GMSH_GET, 0);
+  double use_gen_raise = opt_view_use_gen_raise(current, GMSH_GET, 0);
+  double fake_transparency = opt_view_fake_transparency(current, GMSH_GET, 0);
+  double use_stipple = opt_view_use_stipple(current, GMSH_GET, 0);
 
-void clip_update_cb(CALLBACK_ARGS)
-{
-  int old = CTX.draw_bbox;
-  CTX.draw_bbox = 1;
-  if(CTX.fast_redraw){
-    CTX.post.draw = 0;
-    CTX.mesh.draw = 0;
-  }
+  double normals = opt_view_normals(current, GMSH_GET, 0);
+  double tangents = opt_view_tangents(current, GMSH_GET, 0);
+  double custom_min = opt_view_custom_min(current, GMSH_GET, 0);
+  double custom_max = opt_view_custom_max(current, GMSH_GET, 0);
+  double nb_iso = opt_view_nb_iso(current, GMSH_GET, 0);
+  double offset0 = opt_view_offset0(current, GMSH_GET, 0);
+  double offset1 = opt_view_offset1(current, GMSH_GET, 0);
+  double offset2 = opt_view_offset2(current, GMSH_GET, 0);
+  double transform00 = opt_view_transform00(current, GMSH_GET, 0);
+  double transform01 = opt_view_transform01(current, GMSH_GET, 0);
+  double transform02 = opt_view_transform02(current, GMSH_GET, 0);
+  double transform10 = opt_view_transform10(current, GMSH_GET, 0);
+  double transform11 = opt_view_transform11(current, GMSH_GET, 0);
+  double transform12 = opt_view_transform12(current, GMSH_GET, 0);
+  double transform20 = opt_view_transform20(current, GMSH_GET, 0);
+  double transform21 = opt_view_transform21(current, GMSH_GET, 0);
+  double transform22 = opt_view_transform22(current, GMSH_GET, 0);
+  double raise0 = opt_view_raise0(current, GMSH_GET, 0);
+  double raise1 = opt_view_raise1(current, GMSH_GET, 0);
+  double raise2 = opt_view_raise2(current, GMSH_GET, 0);
+  double timestep = opt_view_timestep(current, GMSH_GET, 0);
+  double arrow_size = opt_view_arrow_size(current, GMSH_GET, 0);
+  double arrow_size_proportional = opt_view_arrow_size_proportional(current, GMSH_GET, 0);
+  double displacement_factor = opt_view_displacement_factor(current, GMSH_GET, 0);
+  double point_size = opt_view_point_size(current, GMSH_GET, 0);
+  double line_width = opt_view_line_width(current, GMSH_GET, 0);
+  double explode = opt_view_explode(current, GMSH_GET, 0);
+  double angle_smooth_normals = opt_view_angle_smooth_normals(current, GMSH_GET, 0);
+  double position0 = opt_view_position0(current, GMSH_GET, 0);
+  double position1 = opt_view_position1(current, GMSH_GET, 0);
+  double size0 = opt_view_size0(current, GMSH_GET, 0);
+  double size1 = opt_view_size1(current, GMSH_GET, 0);
+  double axes_tics0 = opt_view_axes_tics0(current, GMSH_GET, 0);
+  double axes_tics1 = opt_view_axes_tics1(current, GMSH_GET, 0);
+  double axes_tics2 = opt_view_axes_tics2(current, GMSH_GET, 0);
+  double axes_xmin = opt_view_axes_xmin(current, GMSH_GET, 0);
+  double axes_ymin = opt_view_axes_ymin(current, GMSH_GET, 0);
+  double axes_zmin = opt_view_axes_zmin(current, GMSH_GET, 0);
+  double axes_xmax = opt_view_axes_xmax(current, GMSH_GET, 0);
+  double axes_ymax = opt_view_axes_ymax(current, GMSH_GET, 0);
+  double axes_zmax = opt_view_axes_zmax(current, GMSH_GET, 0);
+  double gen_raise_factor = opt_view_gen_raise_factor(current, GMSH_GET, 0);
 
-  int idx = WID->clip_choice->value();
-  CTX.clip[idx] = 0;
-  for(int i = 0; i < WID->clip_browser->size(); i++)
-    if(WID->clip_browser->selected(i+1))
-      CTX.clip[idx] += (1<<i);
-  for(int i = 0; i < 4; i++)
-    CTX.clip_plane[idx][i] = WID->clip_value[i]->value();
-  Draw();
+  char name[256]; strcpy(name, opt_view_name(current, GMSH_GET, NULL));
+  char format[256]; strcpy(format, opt_view_format(current, GMSH_GET, NULL));
+  char axes_label0[256]; strcpy(axes_label0, opt_view_axes_label0(current, GMSH_GET, NULL));
+  char axes_label1[256]; strcpy(axes_label1, opt_view_axes_label1(current, GMSH_GET, NULL));
+  char axes_label2[256]; strcpy(axes_label2, opt_view_axes_label2(current, GMSH_GET, NULL));
+  char axes_format0[256]; strcpy(axes_format0, opt_view_axes_format0(current, GMSH_GET, NULL));
+  char axes_format1[256]; strcpy(axes_format1, opt_view_axes_format1(current, GMSH_GET, NULL));
+  char axes_format2[256]; strcpy(axes_format2, opt_view_axes_format2(current, GMSH_GET, NULL));
+  char gen_raise0[256]; strcpy(gen_raise0, opt_view_gen_raise0(current, GMSH_GET, NULL));
+  char gen_raise1[256]; strcpy(gen_raise1, opt_view_gen_raise1(current, GMSH_GET, NULL));
+  char gen_raise2[256]; strcpy(gen_raise2, opt_view_gen_raise2(current, GMSH_GET, NULL));
 
-  CTX.draw_bbox = old;
-  CTX.post.draw = 1;
-  CTX.mesh.draw = 1;
-}
+  // modify only the views that need to be updated
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
+    if((links == 2 || links == 4) ||
+       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
+       (links == 0 && i == current)) {
 
-void clip_invert_cb(CALLBACK_ARGS)
-{
-  for(int i = 0; i < 4; i++)
-    WID->clip_value[i]->value(-WID->clip_value[i]->value());
-  clip_update_cb(NULL, NULL);
-}
+      if(links == 3 || links == 4)
+        force = 1;
 
-void clip_reset_cb(CALLBACK_ARGS)
-{
-  for(int i = 0; i < 6; i++){
-    CTX.clip[i] = 0;
-    CTX.clip_plane[i][0] = 1.;
-    for(int j = 1; j < 4; j++)
-      CTX.clip_plane[i][j] = 0.;
-  }
-  WID->reset_clip_browser();
-  Draw();
-}
+      double val;
 
-// Manipulator menu
+      // view_choice
 
-void manip_cb(CALLBACK_ARGS)
-{
-  WID->create_manip_window();
-}
+      switch (WID->view_choice[1]->value()) {
+      case 0: val = DRAW_POST_LINEAR; break;
+      case 1: val = DRAW_POST_LOGARITHMIC; break;
+      default: val = DRAW_POST_DOUBLELOGARITHMIC; break; // 2
+      }
+      if(force || (val != scale_type))
+        opt_view_scale_type(i, GMSH_SET, val);
 
-void manip_update_cb(CALLBACK_ARGS)
-{
-  CTX.r[0] = WID->manip_value[0]->value();
-  CTX.r[1] = WID->manip_value[1]->value();
-  CTX.r[2] = WID->manip_value[2]->value();
-  CTX.t[0] = WID->manip_value[3]->value();
-  CTX.t[1] = WID->manip_value[4]->value();
-  CTX.t[2] = WID->manip_value[5]->value();
-  CTX.s[0] = WID->manip_value[6]->value();
-  CTX.s[1] = WID->manip_value[7]->value();
-  CTX.s[2] = WID->manip_value[8]->value();
-  CTX.setQuaternionFromEulerAngles();
-  Draw();
-}
+      switch (WID->view_choice[0]->value()) {
+      case 0: val = DRAW_POST_ISO; break;
+      case 1: val = DRAW_POST_DISCRETE; break;
+      case 2: val = DRAW_POST_CONTINUOUS; break;
+      default: val = DRAW_POST_NUMERIC; break; // 3
+      }
+      if(force || (val != intervals_type))
+	opt_view_intervals_type(i, GMSH_SET, val);
+      
+      val = WID->view_choice[5]->value();
+      if(force || (val != point_type))
+	opt_view_point_type(i, GMSH_SET, val);
+      
+      val = WID->view_choice[6]->value();
+      if(force || (val != line_type))
+        opt_view_line_type(i, GMSH_SET, val);
 
-// Help Menu (if you change the following, please also change the
-// texinfo documentation in doc/texinfo/shortcuts.texi)
+      switch (WID->view_choice[2]->value()) {
+      case 0: val = DRAW_POST_SEGMENT; break;
+      case 1: val = DRAW_POST_ARROW; break;
+      case 2: val = DRAW_POST_PYRAMID; break;
+      case 4: val = DRAW_POST_DISPLACEMENT; break;
+      default: val = DRAW_POST_ARROW3D; break; // 3
+      }
+      if(force || (val != vector_type))
+        opt_view_vector_type(i, GMSH_SET, val);
 
-#if defined(__APPLE__)
-#  define CC(str) "Cmd+" str " "
-#else
-#  define CC(str) "Ctrl+" str
-#endif
+      switch (WID->view_choice[3]->value()) {
+      case 0: val = DRAW_POST_LOCATE_COG; break;
+      default: val = DRAW_POST_LOCATE_VERTEX; break;
+      }
+      if(force || (val != glyph_location))
+        opt_view_glyph_location(i, GMSH_SET, val);
 
-void help_short_cb(CALLBACK_ARGS)
-{
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "Keyboard shortcuts:");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  Left arrow    Go to previous time step"); 
-  Msg(DIRECT, "  Right arrow   Go to next time step"); 
-  Msg(DIRECT, "  Up arrow      Make previous view visible"); 
-  Msg(DIRECT, "  Down arrow    Make next view visible"); 
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  <             Go back to previous context");
-  Msg(DIRECT, "  >             Go forward to next context");
-  Msg(DIRECT, "  0             Reload project file");
-  Msg(DIRECT, "  1 or F1       Mesh lines");
-  Msg(DIRECT, "  2 or F2       Mesh surfaces");
-  Msg(DIRECT, "  3 or F3       Mesh volumes");
-  Msg(DIRECT, "  Escape        Cancel lasso zoom/selection, toggle mouse selection ON/OFF");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  g             Go to geometry module");
-  Msg(DIRECT, "  m             Go to mesh module");
-  Msg(DIRECT, "  p             Go to post-processing module");
-  Msg(DIRECT, "  s             Go to solver module");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  Shift+a       Bring all windows to front");
-  Msg(DIRECT, "  Shift+g       Show geometry options");
-  Msg(DIRECT, "  Shift+m       Show mesh options");
-  Msg(DIRECT, "  Shift+o       Show general options"); 
-  Msg(DIRECT, "  Shift+p       Show post-processing options");
-  Msg(DIRECT, "  Shift+s       Show solver options"); 
-  Msg(DIRECT, "  Shift+w       Show post-processing view options");
-  Msg(DIRECT, "  Shift+Escape  Enable full mouse selection");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  " CC("i") "        Show statistics window"); 
-  Msg(DIRECT, "  " CC("l") "        Show message console");
-#if defined(__APPLE__)
-  Msg(DIRECT, "  " CC("m") "        Minimize window"); 
-#endif
-  Msg(DIRECT, "  " CC("n") "        Create new project file"); 
-  Msg(DIRECT, "  " CC("o") "        Open project file"); 
-  Msg(DIRECT, "  " CC("q") "        Quit");
-  Msg(DIRECT, "  " CC("r") "        Rename project file");
-  Msg(DIRECT, "  " CC("s") "        Save file as");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  Shift+" CC("c") "  Show clipping plane window");
-  Msg(DIRECT, "  Shift+" CC("m") "  Show manipulator window"); 
-  Msg(DIRECT, "  Shift+" CC("n") "  Show option window"); 
-  Msg(DIRECT, "  Shift+" CC("o") "  Merge file(s)"); 
-  Msg(DIRECT, "  Shift+" CC("s") "  Save mesh in default format");
-  Msg(DIRECT, "  Shift+" CC("v") "  Show visibility window");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  Alt+a         Loop through axes modes"); 
-  Msg(DIRECT, "  Alt+b         Hide/show bounding boxes");
-  Msg(DIRECT, "  Alt+c         Loop through predefined color schemes");
-  Msg(DIRECT, "  Alt+f         Change redraw mode (fast/full)"); 
-  Msg(DIRECT, "  Alt+h         Hide/show all post-processing views"); 
-  Msg(DIRECT, "  Alt+i         Hide/show all post-processing view scales");
-  Msg(DIRECT, "  Alt+l         Hide/show geometry lines");
-  Msg(DIRECT, "  Alt+m         Toggle visibility of all mesh entities");
-  Msg(DIRECT, "  Alt+n         Hide/show all post-processing view annotations");
-  Msg(DIRECT, "  Alt+o         Change projection mode (orthographic/perspective)");
-  Msg(DIRECT, "  Alt+p         Hide/show geometry points");
-  Msg(DIRECT, "  Alt+s         Hide/show geometry surfaces");
-  Msg(DIRECT, "  Alt+t         Loop through interval modes for visible post-processing views"); 
-  Msg(DIRECT, "  Alt+v         Hide/show geometry volumes");
-  Msg(DIRECT, "  Alt+w         Enable/disable all lighting");
-  Msg(DIRECT, "  Alt+x         Set X view"); 
-  Msg(DIRECT, "  Alt+y         Set Y view"); 
-  Msg(DIRECT, "  Alt+z         Set Z view"); 
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  Alt+Shift+a   Hide/show small axes"); 
-  Msg(DIRECT, "  Alt+Shift+b   Hide/show mesh volume faces");
-  Msg(DIRECT, "  Alt+Shift+d   Hide/show mesh surface faces");
-  Msg(DIRECT, "  Alt+Shift+l   Hide/show mesh lines");
-  Msg(DIRECT, "  Alt+Shift+o   Adjust projection parameters");
-  Msg(DIRECT, "  Alt+Shift+p   Hide/show mesh points");
-  Msg(DIRECT, "  Alt+Shift+s   Hide/show mesh surface edges");
-  Msg(DIRECT, "  Alt+Shift+v   Hide/show mesh volume edges");
-  Msg(DIRECT, "  Alt+Shift+w   Reverse all mesh normals");
-  Msg(DIRECT, "  Alt+Shift+x   Set -X view"); 
-  Msg(DIRECT, "  Alt+Shift+y   Set -Y view"); 
-  Msg(DIRECT, "  Alt+Shift+z   Set -Z view"); 
-  Msg(DIRECT, " ");
-  WID->create_message_window();
-}
+     switch (WID->view_choice[4]->value()) {
+     case 0: val = DRAW_POST_VONMISES; break;
+     case 2: val = DRAW_POST_LMGC90_TYPE; break;
+     case 3: val = DRAW_POST_LMGC90_COORD; break;
+     case 4: val = DRAW_POST_LMGC90_PRES; break;
+     case 5: val = DRAW_POST_LMGC90_SN; break;
+     case 6: val = DRAW_POST_LMGC90_DEPX; break;
+     case 7: val = DRAW_POST_LMGC90_DEPY; break;
+     case 8: val = DRAW_POST_LMGC90_DEPZ; break;
+     case 9: val = DRAW_POST_LMGC90_DEPAV; break;
+     case 10: val = DRAW_POST_LMGC90_DEPNORM; break;
+     default: val = DRAW_POST_LMGC90; break; // 1
+     }
+     if(force || (val != tensor_type))
+       opt_view_tensor_type(i, GMSH_SET, val);
 
-void help_mouse_cb(CALLBACK_ARGS)
-{
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "Mouse actions:");
-  Msg(DIRECT, " ");
-  Msg(DIRECT, "  Move                - Highlight the elementary geometrical entity");
-  Msg(DIRECT, "                        currently under the mouse pointer and display");
-  Msg(DIRECT, "                        its properties in the status bar");
-  Msg(DIRECT, "                      - Resize a lasso zoom/(un)selection");
-  Msg(DIRECT, "  Left button         - Rotate");
-  Msg(DIRECT, "                      - Select an entity");
-  Msg(DIRECT, "                      - Accept a lasso zoom/selection"); 
-  Msg(DIRECT, "  Ctrl+Left button    Start a lasso zoom/(un)selection"); 
-  Msg(DIRECT, "  Middle button       - Zoom");
-  Msg(DIRECT, "                      - Unselect an entity");
-  Msg(DIRECT, "                      - Accept a lasso zoom/unselection");
-  Msg(DIRECT, "  Ctrl+Middle button  Orthogonalize display"); 
-  Msg(DIRECT, "  Right button        - Pan");
-  Msg(DIRECT, "                      - Cancel a lasso zoom/(un)selection");
-  Msg(DIRECT, "                      - Pop-up menu on post-processing view button");
-  Msg(DIRECT, "  Ctrl+Right button   Reset to default viewpoint");   
-  Msg(DIRECT, " ");   
-  Msg(DIRECT, "  For a 2 button mouse, Middle button = Shift+Left button");
-  Msg(DIRECT, "  For a 1 button mouse, Middle button = Shift+Left button, Right button = Alt+Left button");
-  Msg(DIRECT, " ");
-  WID->create_message_window();
-}
+      switch (WID->view_choice[7]->value()) {
+      case 0: val = DRAW_POST_RANGE_DEFAULT; break;
+      case 1: val = DRAW_POST_RANGE_PER_STEP; break;
+      default: val = DRAW_POST_RANGE_CUSTOM; break; // 2
+      }
+      if(force || (val != range_type))
+        opt_view_range_type(i, GMSH_SET, val);
 
-void help_command_line_cb(CALLBACK_ARGS)
-{
-  Msg(DIRECT, " ");
-  Print_Usage("gmsh");
-  WID->create_message_window();
-}
+      val = WID->view_choice[8]->value();
+      if(force || (val != axes))
+        opt_view_axes(i, GMSH_SET, val);
 
-void help_license_cb(CALLBACK_ARGS)
-{
-  extern void print_license();
-  Msg(DIRECT, " ");
-  print_license();
-  WID->create_message_window();
-}
+      val = WID->view_choice[9]->value();
+      if(force || (val != boundary))
+        opt_view_boundary(i, GMSH_SET, val);
 
-void help_about_cb(CALLBACK_ARGS)
-{
-  WID->create_about_window();
-}
+      val = WID->view_choice[10]->value() - 1;
+      if(force || (val != external_view))
+        opt_view_external_view(i, GMSH_SET, val);
 
-void _replace_multi_format(char *in, char *val, char *out){
-  unsigned int i = 0, j = 0;
+      val = WID->view_choice[11]->value() - 1;
+      if(force || (val != gen_raise_view))
+        opt_view_gen_raise_view(i, GMSH_SET, val);
 
-  out[0] = '\0';
-  while(i < strlen(in)){
-    if(in[i] == '%' && i != strlen(in)-1){
-      if(in[i+1] == 's'){
-	strcat(out, val);
-	i += 2;
-	j += strlen(val);
-      }
-      else{
-	Msg(WARNING, "Skipping unknown format '%%%c' in '%s'", in[i+1], in);
-	i += 2;
+      val = WID->view_choice[12]->value();
+      if(force || (val != show_time))
+        opt_view_show_time(i, GMSH_SET, val);
+      
+      switch(WID->view_choice[13]->value()){
+      case 0: val = DRAW_POST_3D; break;
+      case 1: val = DRAW_POST_2D_SPACE; break;
+      default: val = DRAW_POST_2D_TIME; break; // 2
       }
-    }
-    else{
-      out[j] = in[i];
-      out[j+1] = '\0';
-      i++;
-      j++;
-    }
-  }
-  out[j] = '\0';
-}
-
-void help_online_cb(CALLBACK_ARGS)
-{
-  char prog[1024], cmd[1024];
-  FixWindowsPath(CTX.web_browser, prog);
-  _replace_multi_format(prog, "http://www.geuz.org/gmsh/doc/texinfo/", cmd);
-  SystemCall(cmd);
-}
+      if(force || (val != type))
+        opt_view_type(i, GMSH_SET, val);
 
-void help_credits_cb(CALLBACK_ARGS)
-{
-  char prog[1024], cmd[1024];
-  FixWindowsPath(CTX.web_browser, prog);
-  _replace_multi_format(prog, "http://www.geuz.org/gmsh/doc/CREDITS", cmd);
-  SystemCall(cmd);
-}
+      // view_butts
 
-// Module Menu
+      val = WID->view_butt[0]->value();
+      if(force || (val != arrow_size_proportional))
+        opt_view_arrow_size_proportional(i, GMSH_SET, val);
 
-void mod_geometry_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry, 0);
-}
+      val = WID->view_butt[38]->value();
+      if(force || (val != saturate_values))
+        opt_view_saturate_values(i, GMSH_SET, val);
 
-void mod_mesh_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_mesh, 0);
-}
+      val = WID->view_butt[10]->value();
+      if(force || (val != show_element))
+        opt_view_show_element(i, GMSH_SET, val);
 
-void mod_solver_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_solver, 0);
-}
+      val = WID->view_butt[4]->value();
+      if(force || (val != show_scale))
+        opt_view_show_scale(i, GMSH_SET, val);
 
-void mod_post_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_post, 0);
-}
+      val = WID->view_butt[7]->value();
+      if(force || (val != auto_position))
+        opt_view_auto_position(i, GMSH_SET, val);
 
-void mod_back_cb(CALLBACK_ARGS)
-{
-  WID->set_context(NULL, -1);
-}
+      val = WID->view_butt[25]->value();
+      if(force || (val != axes_auto_position))
+        opt_view_axes_auto_position(i, GMSH_SET, val);
 
-void mod_forward_cb(CALLBACK_ARGS)
-{
-  WID->set_context(NULL, 1);
-}
+      val = WID->view_butt[5]->value();
+      if(force || (val != draw_strings))
+        opt_view_draw_strings(i, GMSH_SET, val);
 
-// Dynamic Geomtry Menus
+      val = WID->view_butt[11]->value();
+      if(force || (val != light))
+        opt_view_light(i, GMSH_SET, val);
 
-void geometry_elementary_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary, 0);
-}
+      val = WID->view_butt[8]->value();
+      if(force || (val != light_lines))
+        opt_view_light_lines(i, GMSH_SET, val);
 
-void geometry_physical_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_physical, 0);
-}
+      val = WID->view_butt[9]->value();
+      if(force || (val != light_two_side))
+        opt_view_light_two_side(i, GMSH_SET, val);
 
-void geometry_edit_cb(CALLBACK_ARGS)
-{
-  char prog[1024], file[1024], cmd[1024];
-  FixWindowsPath(CTX.editor, prog);
-  FixWindowsPath(CTX.filename, file);
-  _replace_multi_format(prog, file, cmd);
-  SystemCall(cmd);
-}
+      val = WID->view_butt[12]->value();
+      if(force || (val != smooth_normals))
+        opt_view_smooth_normals(i, GMSH_SET, val);
 
-void geometry_reload_cb(CALLBACK_ARGS)
-{
-  OpenProblem(CTX.filename);
-  Draw();
-}
+      val = WID->view_menu_butt[0]->menu()[0].value() ? 1 : 0;
+      if(force || (val != draw_scalars))
+        opt_view_draw_scalars(i, GMSH_SET, val);
 
-void geometry_elementary_add_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary_add, 0);
-}
+      val = WID->view_menu_butt[0]->menu()[1].value() ? 1 : 0;
+      if(force || (val != draw_vectors))
+        opt_view_draw_vectors(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary_add_new, 0);
-}
+      val = WID->view_menu_butt[0]->menu()[2].value() ? 1 : 0;
+      if(force || (val != draw_tensors))
+        opt_view_draw_tensors(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_parameter_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(0);
-}
+      val = WID->view_menu_butt[1]->menu()[0].value() ? 1 : 0;
+      if(force || (val != draw_points))
+        opt_view_draw_points(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_point_cb(CALLBACK_ARGS)
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  Draw();
+      val = WID->view_menu_butt[1]->menu()[1].value() ? 1 : 0;
+      if(force || (val != draw_lines))
+        opt_view_draw_lines(i, GMSH_SET, val);
 
-  WID->create_geometry_context_window(1);
+      val = WID->view_menu_butt[1]->menu()[2].value() ? 1 : 0;
+      if(force || (val != draw_triangles))
+        opt_view_draw_triangles(i, GMSH_SET, val);
 
-  while(1) {
-    WID->g_opengl_window->AddPointMode = true;
-    Msg(ONSCREEN, "Move mouse and/or enter coordinates\n"
-	"[Press 'Shift' to hold position, 'e' to add point or 'q' to abort]");
-    std::vector<GVertex*> vertices;
-    std::vector<GEdge*> edges;
-    std::vector<GFace*> faces;
-    std::vector<GRegion*> regions;
-    char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions);
-    if(ib == 'e'){
-      add_point(CTX.filename,
-		(char*)WID->context_geometry_input[2]->value(),
-		(char*)WID->context_geometry_input[3]->value(),
-		(char*)WID->context_geometry_input[4]->value(),
-		(char*)WID->context_geometry_input[5]->value());
-      WID->reset_visibility();
-      Draw();
-    }
-    if(ib == 'q'){
-      WID->g_opengl_window->AddPointMode = false;
-      break;
-    }
-  }
+      val = WID->view_menu_butt[1]->menu()[3].value() ? 1 : 0;
+      if(force || (val != draw_quadrangles))
+        opt_view_draw_quadrangles(i, GMSH_SET, val);
 
-  Msg(ONSCREEN, "");
-}
+      val = WID->view_menu_butt[1]->menu()[4].value() ? 1 : 0;
+      if(force || (val != draw_tetrahedra))
+        opt_view_draw_tetrahedra(i, GMSH_SET, val);
 
-static void _new_multiline(int type)
-{
-  std::vector<GVertex*> vertices;
-  std::vector<GEdge*> edges;
-  std::vector<GFace*> faces;
-  std::vector<GRegion*> regions;
-  int p[100];
+      val = WID->view_menu_butt[1]->menu()[5].value() ? 1 : 0;
+      if(force || (val != draw_hexahedra))
+        opt_view_draw_hexahedra(i, GMSH_SET, val);
 
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  Draw();
+      val = WID->view_menu_butt[1]->menu()[6].value() ? 1 : 0;
+      if(force || (val != draw_prisms))
+        opt_view_draw_prisms(i, GMSH_SET, val);
 
-  int n = 0;
-  while(1) {
-    if(n == 0)
-      Msg(ONSCREEN, "Select control points\n"
-	  "[Press 'e' to end selection or 'q' to abort]");
-    else
-      Msg(ONSCREEN, "Select control points\n"
-	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
-    if(ib == 'l') {
-      for(unsigned int i = 0; i < vertices.size(); i++)
-	p[n++] = vertices[i]->tag();
-    }
-    if(ib == 'r') {
-      Msg(WARNING, "Entity de-selection not supported yet during multi-line creation");
-    }
-    if(ib == 'e') {
-      if(n >= 2) {
-        switch (type) {
-        case 0:
-          add_multline(n, p, CTX.filename);
-          break;
-        case 1:
-          add_spline(n, p, CTX.filename);
-          break;
-        case 2:
-          add_bspline(n, p, CTX.filename);
-          break;
-        case 3:
-          add_bezier(n, p, CTX.filename);
-          break;
-        }
-      }
-      WID->reset_visibility();
-      ZeroHighlight();
-      Draw();
-      n = 0;
-    }
-    if(ib == 'u') {
-      if(n > 0){
-	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
-	Draw();
-	n--;
-      }
-    }
-    if(ib == 'q') {
-      ZeroHighlight();
-      Draw();
-      break;
-    }
-  }
+      val = WID->view_menu_butt[1]->menu()[7].value() ? 1 : 0;
+      if(force || (val != draw_pyramids))
+        opt_view_draw_pyramids(i, GMSH_SET, val);
 
-  Msg(ONSCREEN, "");
-}
+      val = WID->view_butt[6]->value();
+      if(force || (val != use_gen_raise))
+        opt_view_use_gen_raise(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
-{
-  // Disallow multiline selection at the moment, since multilines
-  // dont't work so well...
-  //
-  //_new_multiline(0);
-  //
-  std::vector<GVertex*> vertices;
-  std::vector<GEdge*> edges;
-  std::vector<GFace*> faces;
-  std::vector<GRegion*> regions;
-  int p[100];
+      val = WID->view_butt[24]->value();
+      if(force || (val != fake_transparency))
+        opt_view_fake_transparency(i, GMSH_SET, val);
 
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  Draw();
+      val = WID->view_butt[26]->value();
+      if(force || (val != use_stipple))
+        opt_view_use_stipple(i, GMSH_SET, val);
 
-  int n = 0;
-  while(1) {
-    if(n == 0)
-      Msg(ONSCREEN, "Select start point\n"
-	  "[Press 'q' to abort]");
-    if(n == 1)
-      Msg(ONSCREEN, "Select end point\n"
-	  "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
-    if(ib == 'l') {
-      p[n++] = vertices[0]->tag();
-    }
-    if(ib == 'r') {
-      Msg(WARNING, "Entity de-selection not supported yet during line creation");
-    }
-    if(ib == 'u') {
-      if(n > 0){
-	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
-	Draw();
-	n--;
-      }
-    }
-    if(ib == 'q') {
-      ZeroHighlight();
-      Draw();
-      break;
-    }
-    if(n == 2) {
-      add_multline(2, p, CTX.filename);
-      WID->reset_visibility();
-      ZeroHighlight();
-      Draw();
-      n = 0;
-    }
-  }
+      // view_values
+      
+      val = WID->view_value[0]->value();
+      if(force || (val != normals))
+        opt_view_normals(i, GMSH_SET, val);
 
-  Msg(ONSCREEN, "");
-}
+      val = WID->view_value[1]->value();
+      if(force || (val != tangents))
+        opt_view_tangents(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_spline_cb(CALLBACK_ARGS)
-{
-  _new_multiline(1);
-}
+      val = WID->view_value[31]->value();
+      if(force || (val != custom_min))
+        opt_view_custom_min(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_bspline_cb(CALLBACK_ARGS)
-{
-  _new_multiline(2);
-}
+      val = WID->view_value[32]->value();
+      if(force || (val != custom_max))
+        opt_view_custom_max(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
-{
-  std::vector<GVertex*> vertices;
-  std::vector<GEdge*> edges;
-  std::vector<GFace*> faces;
-  std::vector<GRegion*> regions;
-  int p[100];
+      val = WID->view_value[33]->value();
+      if(force || (val != max_recursion_level))
+        opt_view_max_recursion_level(i, GMSH_SET, val);
 
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  Draw();
+      val = WID->view_value[34]->value();
+      if(force || (val != target_error))
+        opt_view_target_error(i, GMSH_SET, val);
 
-  int n = 0;
-  while(1) {
-    if(n == 0)
-      Msg(ONSCREEN, "Select start point\n"
-	  "[Press 'q' to abort]");
-    if(n == 1)
-      Msg(ONSCREEN, "Select center point\n"
-	  "[Press 'u' to undo last selection or 'q' to abort]");
-    if(n == 2)
-      Msg(ONSCREEN, "Select end point\n"
-	  "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
-    if(ib == 'l') {
-      p[n++] = vertices[0]->tag();
-    }
-    if(ib == 'r') {
-      Msg(WARNING, "Entity de-selection not supported yet during circle creation");
-    }
-    if(ib == 'u') {
-      if(n > 0){
-	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
-	Draw();
-	n--;
-      }
-    }
-    if(ib == 'q') {
-      ZeroHighlight();
-      Draw();
-      break;
-    }
-    if(n == 3) {
-      add_circ(p[0], p[1], p[2], CTX.filename); // begin, center, end
-      WID->reset_visibility();
-      ZeroHighlight();
-      Draw();
-      n = 0;
-    }
-  }
+      val = WID->view_value[30]->value();
+      if(force || (val != nb_iso))
+        opt_view_nb_iso(i, GMSH_SET, val);
 
-  Msg(ONSCREEN, "");
-}
+      val = WID->view_value[40]->value();
+      if(force || (val != offset0))
+        opt_view_offset0(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
-{
-  std::vector<GVertex*> vertices;
-  std::vector<GEdge*> edges;
-  std::vector<GFace*> faces;
-  std::vector<GRegion*> regions;
-  int p[100];
+      val = WID->view_value[41]->value();
+      if(force || (val != offset1))
+        opt_view_offset1(i, GMSH_SET, val);
 
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  Draw();
+      val = WID->view_value[42]->value();
+      if(force || (val != offset2))
+        opt_view_offset2(i, GMSH_SET, val);
 
-  int n = 0;
-  while(1) {
-    if(n == 0)
-      Msg(ONSCREEN, "Select start point\n"
-	  "[Press 'q' to abort]");
-    if(n == 1)
-      Msg(ONSCREEN, "Select center point\n"
-	  "[Press 'u' to undo last selection or 'q' to abort]");
-    if(n == 2)
-      Msg(ONSCREEN, "Select major axis point\n"
-	  "[Press 'u' to undo last selection or 'q' to abort]");
-    if(n == 3)
-      Msg(ONSCREEN, "Select end point\n"
-	  "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
-    if(ib == 'l') {
-      p[n++] = vertices[0]->tag();
-    }
-    if(ib == 'r') {
-      Msg(WARNING, "Entity de-selection not supported yet during ellipse creation");
-    }
-    if(ib == 'u') {
-      if(n > 0){
-	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
-	Draw();
-	n--;
-      }
-    }
-    if(ib == 'q') {
-      ZeroHighlight();
-      Draw();
-      break;
-    }
-    if(n == 4) {
-      add_ell(p[0], p[1], p[2], p[3], CTX.filename);
-      WID->reset_visibility();
-      ZeroHighlight();
-      Draw();
-      n = 0;
-    }
-  }
+      val = WID->view_value[51]->value();
+      if(force || (val != transform00))
+        opt_view_transform00(i, GMSH_SET, val);
 
-  Msg(ONSCREEN, "");
-}
+      val = WID->view_value[52]->value();
+      if(force || (val != transform01))
+        opt_view_transform01(i, GMSH_SET, val);
 
-static void _new_surface_volume(int mode)
-{
-  std::vector<GVertex*> vertices;
-  std::vector<GEdge*> edges;
-  std::vector<GFace*> faces;
-  std::vector<GRegion*> regions;
-  int type, num;
+      val = WID->view_value[53]->value();
+      if(force || (val != transform02))
+        opt_view_transform02(i, GMSH_SET, val);
 
-  List_T *List1 = List_Create(10, 10, sizeof(int));
-  List_T *List2 = List_Create(10, 10, sizeof(int));
+      val = WID->view_value[54]->value();
+      if(force || (val != transform10))
+        opt_view_transform10(i, GMSH_SET, val);
 
-  if(mode == 2) {
-    type = ENT_SURFACE;
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
-    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else {
-    type = ENT_LINE;
-    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  Draw();
+      val = WID->view_value[55]->value();
+      if(force || (val != transform11))
+        opt_view_transform11(i, GMSH_SET, val);
 
-  while(1) {
-    List_Reset(List1);
-    List_Reset(List2);
+      val = WID->view_value[56]->value();
+      if(force || (val != transform12))
+        opt_view_transform12(i, GMSH_SET, val);
 
-    while(1) {
-      if(type == ENT_LINE){
-	if(!List_Nbr(List1))
-	  Msg(ONSCREEN, "Select surface boundary\n"
-	      "[Press 'q' to abort]");
-	else
-	  Msg(ONSCREEN, "Select surface boundary\n"
-	      "[Press 'u' to undo last selection or 'q' to abort]");
-      }
-      else{
-	if(!List_Nbr(List1))
-	  Msg(ONSCREEN, "Select volume boundary\n"
-	      "[Press 'q' to abort]");
-	else
-	  Msg(ONSCREEN, "Select volume boundary\n"
-	      "[Press 'u' to undo last selection or 'q' to abort]");
-      }
+      val = WID->view_value[57]->value();
+      if(force || (val != transform20))
+        opt_view_transform20(i, GMSH_SET, val);
 
-      char ib = SelectEntity(type, vertices, edges, faces, regions);
-      if(ib == 'q') {
-        ZeroHighlight();
-        Draw();
-        goto stopall;
-      }
-      if(ib == 'u') {
-	if(List_Nbr(List1) > 0){
-	  List_Read(List1, List_Nbr(List1)-1, &num);
-	  ZeroHighlightEntityNum(0,
-				 (type == ENT_LINE) ? abs(num) : 0, 
-				 (type != ENT_LINE) ? abs(num) : 0,
-				 0);
-	  List_Pop(List1);
-	  Draw();
-	}
-      }
-      if(ib == 'r') {
-	Msg(WARNING, "Entity de-selection not supported yet during surface/volume creation");
-      }
-      if(ib == 'l') {
-	int num = (type == ENT_LINE) ? edges[0]->tag() : faces[0]->tag();
-	if(SelectContour(type, num, List1)) {
-	  if(type == ENT_LINE)
-	    add_lineloop(List1, CTX.filename, &num);
-	  else
-	    add_surfloop(List1, CTX.filename, &num);
-	  List_Reset(List1);
-	  List_Add(List2, &num);
-	  while(1) {
-	    if(!List_Nbr(List1))
-	      Msg(ONSCREEN, "Select hole boundaries (if none, press 'e')\n"
-		  "[Press 'e' to end selection or 'q' to abort]");
-	    else
-	      Msg(ONSCREEN, "Select hole boundaries\n"
-		  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-	    ib = SelectEntity(type, vertices, edges, faces, regions);
-	    if(ib == 'q') {
-	      ZeroHighlight();
-	      Draw();
-	      goto stopall;
-	    }
-	    if(ib == 'e') {
-	      ZeroHighlight();
-	      Draw();
-	      List_Reset(List1);
-	      break;
-	    }
-	    if(ib == 'u') {
-	      if(List_Nbr(List1) > 0){
-		List_Read(List1, List_Nbr(List1)-1, &num);
-		ZeroHighlightEntityNum(0,
-				       (type == ENT_LINE) ? abs(num) : 0, 
-				       (type != ENT_LINE) ? abs(num) : 0,
-				       0);
-		List_Pop(List1);
-		Draw();
-	      }
-	    }
-	    if(ib == 'l') {
-	      num = (type == ENT_LINE) ? edges[0]->tag() : faces[0]->tag();
-	      if(SelectContour(type, num, List1)) {
-		if(type == ENT_LINE)
-		  add_lineloop(List1, CTX.filename, &num);
-		else
-		  add_surfloop(List1, CTX.filename, &num);
-		List_Reset(List1);
-		List_Add(List2, &num);
-	      }
-	    }
-	    if(ib == 'r') {
-	      Msg(WARNING, "Entity de-selection not supported yet during surface/volume creation");
-	    }
-	  }
-	  if(List_Nbr(List2)) {
-	    switch (mode) {
-	    case 0: add_surf(List2, CTX.filename, 0, 2); break;
-	    case 1: add_surf(List2, CTX.filename, 0, 1); break;
-	    case 2: add_vol(List2, CTX.filename); break;
-	    }
-	    WID->reset_visibility();
-	    ZeroHighlight();
-	    Draw();
-	    break;
-	  }
-	} // if SelectContour
-      }
-    }
-  }
+      val = WID->view_value[58]->value();
+      if(force || (val != transform21))
+        opt_view_transform21(i, GMSH_SET, val);
 
-stopall:;
-  List_Delete(List1);
-  List_Delete(List2);
+      val = WID->view_value[59]->value();
+      if(force || (val != transform22))
+        opt_view_transform22(i, GMSH_SET, val);
 
-  Msg(ONSCREEN, "");
-}
+      val = WID->view_value[43]->value();
+      if(force || (val != raise0))
+        opt_view_raise0(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_planesurface_cb(CALLBACK_ARGS)
-{
-  _new_surface_volume(0);
-}
+      val = WID->view_value[44]->value();
+      if(force || (val != raise1))
+        opt_view_raise1(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_ruledsurface_cb(CALLBACK_ARGS)
-{
-  _new_surface_volume(1);
-}
+      val = WID->view_value[45]->value();
+      if(force || (val != raise2))
+        opt_view_raise2(i, GMSH_SET, val);
 
-void geometry_elementary_add_new_volume_cb(CALLBACK_ARGS)
-{
-  _new_surface_volume(2);
-}
+      val = WID->view_value[50]->value();
+      if(force || (val != timestep))
+        opt_view_timestep(i, GMSH_SET, val);
 
-static void _action_point_line_surface_volume(int action, int mode, char *what)
-{
-  std::vector<GVertex*> vertices;
-  std::vector<GEdge*> edges;
-  std::vector<GFace*> faces;
-  std::vector<GRegion*> regions;
-  int type;
-  char *str;
+      val = WID->view_value[60]->value();
+      if(force || (val != arrow_size))
+        opt_view_arrow_size(i, GMSH_SET, val);
 
-  if(!strcmp(what, "Point")) {
-    type = ENT_POINT;
-    str = "points";
-    opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else if(!strcmp(what, "Line")) {
-    type = ENT_LINE;
-    str = "lines";
-    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else if(!strcmp(what, "Surface")) {
-    type = ENT_SURFACE;
-    str = "surfaces";
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else if(!strcmp(what, "Volume")) {
-    type = ENT_VOLUME;
-    str = "volumes";
-    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else{
-    Msg(GERROR, "Unknown entity to select");
-    return;
-  }
+      val = WID->view_value[63]->value();
+      if(force || (val != displacement_factor))
+        opt_view_displacement_factor(i, GMSH_SET, val);
 
-  if(action == 8){
-    WID->create_mesh_context_window(0);
-  }
-  else if(action == 10){
-    Msg(GERROR, "BDS->classify(angle, edge_prolongation) must be reinterfaced");
-  }
+      val = WID->view_value[61]->value();
+      if(force || (val != point_size))
+        opt_view_point_size(i, GMSH_SET, val);
 
-  Draw();
-    
-  List_T *List1 = List_Create(5, 5, sizeof(int));
-  while(1) {
-    if(!List_Nbr(List1))
-      Msg(ONSCREEN, "Select %s\n"
-	  "[Press 'e' to end selection or 'q' to abort]", str);
-    else
-      Msg(ONSCREEN, "Select %s\n"
-	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
+      val = WID->view_value[62]->value();
+      if(force || (val != line_width))
+        opt_view_line_width(i, GMSH_SET, val);
 
-    char ib = SelectEntity(type, vertices, edges, faces, regions);
-    if(ib == 'l') {
-      // we don't use List_Insert in order to keep the original
-      // ordering (this is slower, but this way undo works as
-      // expected)
-      int tag;
-      switch (type) {
-      case ENT_POINT: 
-	for(unsigned int i = 0; i < vertices.size(); i++){
-	  tag = vertices[i]->tag();
-	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-	    List_Add(List1, &tag);
-	}
-	break;
-      case ENT_LINE:
-	for(unsigned int i = 0; i < edges.size(); i++){
-	  tag = edges[i]->tag();
-	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-	    List_Add(List1, &tag);
-	}
-	break;
-      case ENT_SURFACE:
-	for(unsigned int i = 0; i < faces.size(); i++){
-	  tag = faces[i]->tag();
-	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-	    List_Add(List1, &tag);
-	}
-	break;
-      case ENT_VOLUME:
-	for(unsigned int i = 0; i < regions.size(); i++){
-	  tag = regions[i]->tag();
-	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-	    List_Add(List1, &tag);
-	}
-	break;
-      }
-    }
-    if(ib == 'r') {
-      // we don't use List_Suppress in order to keep the original
-      // ordering (this is slower, but this way undo works as
-      // expected)
-      int index, tag;
-      switch (type) {
-      case ENT_POINT:
-	for(unsigned int i = 0; i < vertices.size(); i++){
-	  tag = vertices[i]->tag();
-	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
-	  if(index >= 0) List_PSuppress(List1, index);
-	  ZeroHighlightEntityNum(tag, 0, 0, 0);
-	}
-	break;
-      case ENT_LINE:
-	for(unsigned int i = 0; i < edges.size(); i++){
-	  tag = edges[i]->tag();
-	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
-	  if(index >= 0) List_PSuppress(List1, index);
-	  ZeroHighlightEntityNum(0, tag, 0, 0);
-	}
-	break;
-      case ENT_SURFACE:
-	for(unsigned int i = 0; i < faces.size(); i++){
-	  tag = faces[i]->tag();
-	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
-	  if(index >= 0) List_PSuppress(List1, index);
-	  ZeroHighlightEntityNum(0, 0, tag, 0);
-	}
-	break;
-      case ENT_VOLUME:
-	for(unsigned int i = 0; i < regions.size(); i++){
-	  tag = regions[i]->tag();
-	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
-	  if(index >= 0) List_PSuppress(List1, index);
-	  ZeroHighlightEntityNum(0, 0, 0, tag);
-	}
-	break;
-      }
-      Draw();
-    }
-    if(ib == 'u') {
-      if(List_Nbr(List1)) {
-	int num;
-	List_Read(List1, List_Nbr(List1) - 1, &num);
-	ZeroHighlightEntityNum((type == ENT_POINT) ? num : 0,
-			       (type == ENT_LINE) ? num : 0,
-			       (type == ENT_SURFACE) ? num : 0,
-			       (type == ENT_VOLUME) ? num : 0);
-	Draw();
-	List_Pop(List1);
-      }
-    }
-    if(ib == 'e') {
-      if(List_Nbr(List1)){
-	switch (action) {
-	case 0:
-	  translate(mode, List1, CTX.filename, what,
-		    (char*)WID->context_geometry_input[6]->value(),
-		    (char*)WID->context_geometry_input[7]->value(),
-		    (char*)WID->context_geometry_input[8]->value());
-	  break;
-	case 1:
-	  rotate(mode, List1, CTX.filename, what,
-		 (char*)WID->context_geometry_input[12]->value(),
-		 (char*)WID->context_geometry_input[13]->value(),
-		 (char*)WID->context_geometry_input[14]->value(),
-		 (char*)WID->context_geometry_input[9]->value(),
-		 (char*)WID->context_geometry_input[10]->value(),
-		 (char*)WID->context_geometry_input[11]->value(),
-		 (char*)WID->context_geometry_input[15]->value());
-	  break;
-	case 2:
-	  dilate(mode, List1, CTX.filename, what,
-		 (char*)WID->context_geometry_input[16]->value(),
-		 (char*)WID->context_geometry_input[17]->value(),
-		 (char*)WID->context_geometry_input[18]->value(),
-		 (char*)WID->context_geometry_input[19]->value());
-	  break;
-	case 3:
-	  symmetry(mode, List1, CTX.filename, what,
-		   (char*)WID->context_geometry_input[20]->value(),
-		   (char*)WID->context_geometry_input[21]->value(),
-		   (char*)WID->context_geometry_input[22]->value(),
-		   (char*)WID->context_geometry_input[23]->value());
-	  break;
-	case 4:
-	  extrude(List1, CTX.filename, what,
-		  (char*)WID->context_geometry_input[6]->value(),
-		  (char*)WID->context_geometry_input[7]->value(),
-		  (char*)WID->context_geometry_input[8]->value());
-	  break;
-	case 5:
-	  protude(List1, CTX.filename, what,
-		  (char*)WID->context_geometry_input[12]->value(),
-		  (char*)WID->context_geometry_input[13]->value(),
-		  (char*)WID->context_geometry_input[14]->value(),
-		  (char*)WID->context_geometry_input[9]->value(),
-		  (char*)WID->context_geometry_input[10]->value(),
-		  (char*)WID->context_geometry_input[11]->value(),
-		  (char*)WID->context_geometry_input[15]->value());
-	  break;
-	case 6:
-	  delet(List1, CTX.filename, what);
-	  break;
-	case 7:
-	  add_physical(List1, CTX.filename, type);
-	  break;
-	case 8:
-	  add_charlength(List1, CTX.filename, (char*)WID->context_mesh_input[0]->value());
-	  break;
-	case 9:
-	  add_recosurf(List1, CTX.filename);
-	  break;
-	case 10:
-	  Msg(GERROR, "BDS->get_geom and set status must be reinterfaced");
-	  break;
-	default:
-	  Msg(GERROR, "Unknown action on selected entities");
-	  break;
-	}
-	List_Reset(List1);
-	WID->reset_visibility();
-	ZeroHighlight();
-	if(action <= 6) SetBoundingBox();
-	Draw();
+      val = WID->view_value[12]->value();
+      if(force || (val != explode))
+        opt_view_explode(i, GMSH_SET, val);
+
+      val = WID->view_value[10]->value();
+      if(force || (val != angle_smooth_normals))
+        opt_view_angle_smooth_normals(i, GMSH_SET, val);
+
+      val = WID->view_value[20]->value();
+      if(force || (val != position0))
+        opt_view_position0(i, GMSH_SET, val);
+
+      val = WID->view_value[21]->value();
+      if(force || (val != position1))
+        opt_view_position1(i, GMSH_SET, val);
+
+      val = WID->view_value[22]->value();
+      if(force || (val != size0))
+        opt_view_size0(i, GMSH_SET, val);
+      
+      val = WID->view_value[23]->value();
+      if(force || (val != size1))
+        opt_view_size1(i, GMSH_SET, val);
+
+      val = WID->view_value[13]->value();
+      if(force || (val != axes_xmin))
+        opt_view_axes_xmin(i, GMSH_SET, val);
+
+      val = WID->view_value[14]->value();
+      if(force || (val != axes_ymin))
+        opt_view_axes_ymin(i, GMSH_SET, val);
+
+      val = WID->view_value[15]->value();
+      if(force || (val != axes_zmin))
+        opt_view_axes_zmin(i, GMSH_SET, val);
+
+      val = WID->view_value[16]->value();
+      if(force || (val != axes_xmax))
+        opt_view_axes_xmax(i, GMSH_SET, val);
+
+      val = WID->view_value[17]->value();
+      if(force || (val != axes_ymax))
+        opt_view_axes_ymax(i, GMSH_SET, val);
+
+      val = WID->view_value[18]->value();
+      if(force || (val != axes_zmax))
+        opt_view_axes_zmax(i, GMSH_SET, val);
+
+      val = WID->view_value[2]->value();
+      if(force || (val != gen_raise_factor))
+        opt_view_gen_raise_factor(i, GMSH_SET, val);
+
+      val = WID->view_value[3]->value();
+      if(force || (val != axes_tics0))
+        opt_view_axes_tics0(i, GMSH_SET, val);
+
+      val = WID->view_value[4]->value();
+      if(force || (val != axes_tics1))
+        opt_view_axes_tics1(i, GMSH_SET, val);
+
+      val = WID->view_value[5]->value();
+      if(force || (val != axes_tics2))
+        opt_view_axes_tics2(i, GMSH_SET, val);
+
+      // view_inputs
+
+      char *str;
+
+      str = (char *)WID->view_input[0]->value();
+      if(force || strcmp(str, name))
+        opt_view_name(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[1]->value();
+      if(force || strcmp(str, format))
+        opt_view_format(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[10]->value();
+      if(force || strcmp(str, axes_label0))
+        opt_view_axes_label0(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[11]->value();
+      if(force || strcmp(str, axes_label1))
+        opt_view_axes_label1(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[12]->value();
+      if(force || strcmp(str, axes_label2))
+        opt_view_axes_label2(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[7]->value();
+      if(force || strcmp(str, axes_format0))
+        opt_view_axes_format0(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[8]->value();
+      if(force || strcmp(str, axes_format1))
+        opt_view_axes_format1(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[9]->value();
+      if(force || strcmp(str, axes_format2))
+        opt_view_axes_format2(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[4]->value();
+      if(force || strcmp(str, gen_raise0))
+        opt_view_gen_raise0(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[5]->value();
+      if(force || strcmp(str, gen_raise1))
+        opt_view_gen_raise1(i, GMSH_SET, str);
+
+      str = (char *)WID->view_input[6]->value();
+      if(force || strcmp(str, gen_raise2))
+        opt_view_gen_raise2(i, GMSH_SET, str);
+
+      // colors (since the color buttons modify the values directly
+      // through callbacks, we can use the opt_XXX routines directly)
+      if(force || (i != current)){
+        opt_view_color_points(i, GMSH_SET, opt_view_color_points(current, GMSH_GET, 0));
+	opt_view_color_lines(i, GMSH_SET, opt_view_color_lines(current, GMSH_GET, 0));
+	opt_view_color_triangles(i, GMSH_SET, opt_view_color_triangles(current, GMSH_GET, 0));
+	opt_view_color_quadrangles(i, GMSH_SET, opt_view_color_quadrangles(current, GMSH_GET, 0));
+        opt_view_color_tetrahedra(i, GMSH_SET, opt_view_color_tetrahedra(current, GMSH_GET, 0));
+        opt_view_color_hexahedra(i, GMSH_SET, opt_view_color_hexahedra(current, GMSH_GET, 0));
+        opt_view_color_prisms(i, GMSH_SET, opt_view_color_prisms(current, GMSH_GET, 0));
+        opt_view_color_pyramids(i, GMSH_SET, opt_view_color_pyramids(current, GMSH_GET, 0));
+        opt_view_color_tangents(i, GMSH_SET, opt_view_color_tangents(current, GMSH_GET, 0));
+        opt_view_color_normals(i, GMSH_SET, opt_view_color_normals(current, GMSH_GET, 0));
+        opt_view_color_text2d(i, GMSH_SET, opt_view_color_text2d(current, GMSH_GET, 0));
+        opt_view_color_text3d(i, GMSH_SET, opt_view_color_text3d(current, GMSH_GET, 0));
+        opt_view_color_axes(i, GMSH_SET, opt_view_color_axes(current, GMSH_GET, 0));
       }
-    }
-    if(ib == 'q') {
-      if(action == 10){
-	Msg(GERROR, "BDS->classify() must be reinterfaced");
+
+      // colorbar window
+
+      if(force || (i != current)) {
+	Post_View *src = *(Post_View **)List_Pointer(CTX.post.list, current);
+	Post_View *dest = *(Post_View **)List_Pointer(CTX.post.list, i);
+        ColorTable_Copy(&src->CT);
+        ColorTable_Paste(&dest->CT);
+	dest->Changed = 1;
       }
-      ZeroHighlight();
-      Draw();
-      break;
     }
   }
-  List_Delete(List1);
-
-  Msg(ONSCREEN, "");
-}
-  
-void geometry_elementary_add_translate_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary_add_translate, 0);
-}
 
-void geometry_elementary_add_translate_point_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(0, 1, "Point");
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
+  Draw();
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
-void geometry_elementary_add_translate_line_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(0, 1, "Line");
-}
+// Statistics Menu
 
-void geometry_elementary_add_translate_surface_cb(CALLBACK_ARGS)
+void statistics_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(0, 1, "Surface");
+  WID->create_statistics_window();
 }
 
-void geometry_elementary_translate_cb(CALLBACK_ARGS)
+void statistics_update_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_translate, 0);
+  WID->set_statistics(true);
 }
 
-void geometry_elementary_translate_point_cb(CALLBACK_ARGS)
+void statistics_histogram_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(0, 0, "Point");
+  char *name = (char*)data;
+  int type;
+  if(!strcmp(name, "Gamma"))
+    type = 0;
+  else if(!strcmp(name, "Eta"))
+    type = 1;
+  else
+    type = 2;
+  Create2DGraph(name, "# Elements", 100, 0, WID->quality[type]);
+  Draw();
 }
 
-void geometry_elementary_translate_line_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(0, 0, "Line");
-}
+// Messages Menu
 
-void geometry_elementary_translate_surface_cb(CALLBACK_ARGS)
+void message_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(0, 0, "Surface");
+  WID->create_message_window();
 }
 
-void geometry_elementary_add_rotate_cb(CALLBACK_ARGS)
+void message_copy_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_add_rotate, 0);
+#define BUFFL 50000
+  static char buff[BUFFL];
+  strcpy(buff, "");
+  for(int i = 1; i <= WID->msg_browser->size(); i++) {
+    if(WID->msg_browser->selected(i)) {
+      const char *c = WID->msg_browser->text(i);
+      if(strlen(buff) + strlen(c) > BUFFL - 2) {
+        Msg(GERROR, "Text selection too large to copy");
+        break;
+      }
+      if(c[0] == '@')
+        strcat(buff, &c[5]);
+      else
+        strcat(buff, c);
+      strcat(buff, "\n");
+    }
+  }
+  // bof bof bof
+  Fl::copy(buff, strlen(buff), 0);
+  Fl::copy(buff, strlen(buff), 1);
 }
 
-void geometry_elementary_add_rotate_point_cb(CALLBACK_ARGS)
+void message_clear_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(1, 1, "Point");
+  WID->msg_browser->clear();
 }
 
-void geometry_elementary_add_rotate_line_cb(CALLBACK_ARGS)
+void message_save_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(1, 1, "Line");
+ test:
+  if(file_chooser(0, 1, "Save", "*")) {
+    char *name = file_chooser_get_name(1);
+    if(CTX.confirm_overwrite) {
+      if(!StatFile(name))
+        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", 
+		      "Cancel", "Replace", NULL, name))
+          goto test;
+    }
+    WID->save_message(name);
+  }
 }
 
-void geometry_elementary_add_rotate_surface_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(1, 1, "Surface");
-}
+// Visibility Menu
 
-void geometry_elementary_rotate_cb(CALLBACK_ARGS)
+void visibility_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_rotate, 0);
+  // get the visibility info from the model, and update the browser accordingly
+  WID->create_visibility_window();
+  WID->vis_browser->clear();
+  VisibilityManager::instance()->update(WID->vis_type->value());
+  for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){
+    WID->vis_browser->add(VisibilityManager::instance()->getBrowserLine(i).c_str());
+    if(VisibilityManager::instance()->getVisibility(i))
+      WID->vis_browser->select(i + 1);
+  }
+  // active the delete button for physicals and partitions only!
+  if(WID->vis_type->value() == 1 || WID->vis_type->value() == 2)
+    WID->vis_push_butt[0]->activate();
+  else
+    WID->vis_push_butt[0]->deactivate();
 }
 
-void geometry_elementary_rotate_point_cb(CALLBACK_ARGS)
+void visibility_ok_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(1, 0, "Point");
+  // if the browser is not empty, get the selections made in the
+  // browser and apply them into the model
+  if(VisibilityManager::instance()->getNumEntities()){
+    CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
+    VisibilityManager::instance()->setAllInvisible(WID->vis_type->value());
+    for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++)
+      if(WID->vis_browser->selected(i + 1))
+	VisibilityManager::instance()->setVisibility(i, true, WID->vis_butt[0]->value());
+    // then refresh the browser to account for recursive selections
+    for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++)
+      if(VisibilityManager::instance()->getVisibility(i))
+	WID->vis_browser->select(i + 1);
+    Draw();
+  }
 }
 
-void geometry_elementary_rotate_line_cb(CALLBACK_ARGS)
+void visibility_save_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(1, 0, "Line");
+  visibility_ok_cb(NULL, NULL);
+  std::string str = VisibilityManager::instance()->getStringForGEO();
+  add_infile((char*)str.c_str(), CTX.filename);
 }
 
-void geometry_elementary_rotate_surface_cb(CALLBACK_ARGS)
+void visibility_delete_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(1, 0, "Surface");
+  if(WID->vis_type->value() == 1)
+    GMODEL->deletePhysicalGroups();
+  else if(WID->vis_type->value() == 2)
+    GMODEL->deleteMeshPartitions();
+  visibility_cb(NULL, NULL);
 }
 
-void geometry_elementary_add_scale_cb(CALLBACK_ARGS)
+void visibility_sort_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_add_scale, 0);
-}
+  char *str = (char*)data;
+  int val;
+  if(!strcmp(str, "type"))
+    val = 1;
+  else if(!strcmp(str, "number"))
+    val = 2;
+  else if(!strcmp(str, "name"))
+    val = 3;
+  else if(!strcmp(str, "-"))
+    val = -1;
+  else if(!strcmp(str, "+"))
+    val = -2;
+  else
+    val = 0;
 
-void geometry_elementary_add_scale_point_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(4);
-  _action_point_line_surface_volume(2, 1, "Point");
+  if(val == 0) { // select or deselect everything
+    int selectall = 0;
+    for(int i = 0; i < WID->vis_browser->size(); i++)
+      if(!WID->vis_browser->selected(i + 1)) {
+        selectall = 1;
+        break;
+      }
+    if(selectall)
+      for(int i = 0; i < WID->vis_browser->size(); i++)
+        WID->vis_browser->select(i + 1);
+    else
+      WID->vis_browser->deselect();
+  }
+  else if(val == -1){ // invert the selection
+    int *state = new int[WID->vis_browser->size()];
+    for(int i = 0; i < WID->vis_browser->size(); i++)
+      state[i] = WID->vis_browser->selected(i + 1);
+    WID->vis_browser->deselect();
+    for(int i = 0; i < WID->vis_browser->size(); i++)
+      if(!state[i]) WID->vis_browser->select(i + 1);
+    delete [] state;
+  }
+  else if(val == -2){ // create new parameter name for selection
+    for(int i = 0; i < WID->vis_browser->size(); i++){
+      if(WID->vis_browser->selected(i + 1)){
+	static char tmpstr[256];
+	sprintf(tmpstr, "%d", VisibilityManager::instance()->getTag(i));
+	WID->context_geometry_input[1]->value(tmpstr);
+	break;
+      }
+    }
+    WID->context_geometry_input[0]->value("NewName");
+    WID->create_geometry_context_window(0);
+  }
+  else { // set new sorting mode
+    VisibilityManager::instance()->setSortMode(val);
+    visibility_cb(NULL, NULL);
+  }
 }
 
-void geometry_elementary_add_scale_line_cb(CALLBACK_ARGS)
+void visibility_number_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(4);
-  _action_point_line_surface_volume(2, 1, "Line");
-}
+  CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
 
-void geometry_elementary_add_scale_surface_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(4);
-  _action_point_line_surface_volume(2, 1, "Surface");
+  int type = (int)(long)data;
+  bool val;
+  if(type >= 100){ // show
+    val = true;
+    type -= 100;
+  }
+  else{ // hide
+    val = false;
+  }
+  
+  char *str = (char *)WID->vis_input[type]->value();  
+  int all = !strcmp(str, "all") || !strcmp(str, "*");
+  int num = all ? 0 : atoi(str); 
+  VisibilityManager::instance()->setVisibilityByNumber(type, num, all, val);
+  int pos = WID->vis_browser->position();
+  visibility_cb(NULL, NULL);
+  WID->vis_browser->position(pos);
+  Draw();
 }
 
-void geometry_elementary_scale_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary_scale, 0);
-}
+// Clipping planes menu
 
-void geometry_elementary_scale_point_cb(CALLBACK_ARGS)
+void clip_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(4);
-  _action_point_line_surface_volume(2, 0, "Point");
+  WID->create_clip_window();
 }
 
-void geometry_elementary_scale_line_cb(CALLBACK_ARGS)
+void clip_num_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(4);
-  _action_point_line_surface_volume(2, 0, "Line");
+  WID->reset_clip_browser();
 }
 
-void geometry_elementary_scale_surface_cb(CALLBACK_ARGS)
+void clip_update_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(4);
-  _action_point_line_surface_volume(2, 0, "Surface");
-}
+  int idx = WID->clip_choice->value();
+  CTX.clip[idx] = 0;
+  for(int i = 0; i < WID->clip_browser->size(); i++)
+    if(WID->clip_browser->selected(i+1))
+      CTX.clip[idx] += (1<<i);
+  for(int i = 0; i < 4; i++)
+    CTX.clip_plane[idx][i] = WID->clip_value[i]->value();
 
-void geometry_elementary_add_symmetry_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary_add_symmetry, 0);
+  int old = CTX.draw_bbox;
+  CTX.draw_bbox = 1;
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
+  Draw();
+  CTX.draw_bbox = old;
+  CTX.post.draw = CTX.mesh.draw = 1;
 }
 
-void geometry_elementary_add_symmetry_point_cb(CALLBACK_ARGS)
+void clip_invert_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(5);
-  _action_point_line_surface_volume(3, 1, "Point");
+  for(int i = 0; i < 4; i++)
+    WID->clip_value[i]->value(-WID->clip_value[i]->value());
+  clip_update_cb(NULL, NULL);
 }
 
-void geometry_elementary_add_symmetry_line_cb(CALLBACK_ARGS)
+void clip_reset_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(5);
-  _action_point_line_surface_volume(3, 1, "Line");
+  for(int i = 0; i < 6; i++){
+    CTX.clip[i] = 0;
+    CTX.clip_plane[i][0] = 1.;
+    for(int j = 1; j < 4; j++)
+      CTX.clip_plane[i][j] = 0.;
+  }
+  WID->reset_clip_browser();
+  Draw();
 }
 
-void geometry_elementary_add_symmetry_surface_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(5);
-  _action_point_line_surface_volume(3, 1, "Surface");
-}
+// Manipulator menu
 
-void geometry_elementary_symmetry_cb(CALLBACK_ARGS)
+void manip_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_symmetry, 0);
+  WID->create_manip_window();
 }
 
-void geometry_elementary_symmetry_point_cb(CALLBACK_ARGS)
+void manip_update_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(5);
-  _action_point_line_surface_volume(3, 0, "Point");
+  CTX.r[0] = WID->manip_value[0]->value();
+  CTX.r[1] = WID->manip_value[1]->value();
+  CTX.r[2] = WID->manip_value[2]->value();
+  CTX.t[0] = WID->manip_value[3]->value();
+  CTX.t[1] = WID->manip_value[4]->value();
+  CTX.t[2] = WID->manip_value[5]->value();
+  CTX.s[0] = WID->manip_value[6]->value();
+  CTX.s[1] = WID->manip_value[7]->value();
+  CTX.s[2] = WID->manip_value[8]->value();
+  CTX.setQuaternionFromEulerAngles();
+  Draw();
 }
 
-void geometry_elementary_symmetry_line_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(5);
-  _action_point_line_surface_volume(3, 0, "Line");
-}
+// Help Menu (if you change the following, please also change the
+// texinfo documentation in doc/texinfo/shortcuts.texi)
 
-void geometry_elementary_symmetry_surface_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(5);
-  _action_point_line_surface_volume(3, 0, "Surface");
-}
+#if defined(__APPLE__)
+#  define CC(str) "Cmd+" str " "
+#else
+#  define CC(str) "Ctrl+" str
+#endif
 
-void geometry_elementary_extrude_cb(CALLBACK_ARGS)
+void help_short_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_extrude, 0);
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "Keyboard shortcuts:");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  Left arrow    Go to previous time step"); 
+  Msg(DIRECT, "  Right arrow   Go to next time step"); 
+  Msg(DIRECT, "  Up arrow      Make previous view visible"); 
+  Msg(DIRECT, "  Down arrow    Make next view visible"); 
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  <             Go back to previous context");
+  Msg(DIRECT, "  >             Go forward to next context");
+  Msg(DIRECT, "  0             Reload project file");
+  Msg(DIRECT, "  1 or F1       Mesh lines");
+  Msg(DIRECT, "  2 or F2       Mesh surfaces");
+  Msg(DIRECT, "  3 or F3       Mesh volumes");
+  Msg(DIRECT, "  Escape        Cancel lasso zoom/selection, toggle mouse selection ON/OFF");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  g             Go to geometry module");
+  Msg(DIRECT, "  m             Go to mesh module");
+  Msg(DIRECT, "  p             Go to post-processing module");
+  Msg(DIRECT, "  s             Go to solver module");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  Shift+a       Bring all windows to front");
+  Msg(DIRECT, "  Shift+g       Show geometry options");
+  Msg(DIRECT, "  Shift+m       Show mesh options");
+  Msg(DIRECT, "  Shift+o       Show general options"); 
+  Msg(DIRECT, "  Shift+p       Show post-processing options");
+  Msg(DIRECT, "  Shift+s       Show solver options"); 
+  Msg(DIRECT, "  Shift+w       Show post-processing view options");
+  Msg(DIRECT, "  Shift+Escape  Enable full mouse selection");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  " CC("i") "        Show statistics window"); 
+  Msg(DIRECT, "  " CC("l") "        Show message console");
+#if defined(__APPLE__)
+  Msg(DIRECT, "  " CC("m") "        Minimize window"); 
+#endif
+  Msg(DIRECT, "  " CC("n") "        Create new project file"); 
+  Msg(DIRECT, "  " CC("o") "        Open project file"); 
+  Msg(DIRECT, "  " CC("q") "        Quit");
+  Msg(DIRECT, "  " CC("r") "        Rename project file");
+  Msg(DIRECT, "  " CC("s") "        Save file as");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  Shift+" CC("c") "  Show clipping plane window");
+  Msg(DIRECT, "  Shift+" CC("m") "  Show manipulator window"); 
+  Msg(DIRECT, "  Shift+" CC("n") "  Show option window"); 
+  Msg(DIRECT, "  Shift+" CC("o") "  Merge file(s)"); 
+  Msg(DIRECT, "  Shift+" CC("s") "  Save mesh in default format");
+  Msg(DIRECT, "  Shift+" CC("v") "  Show visibility window");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  Alt+a         Loop through axes modes"); 
+  Msg(DIRECT, "  Alt+b         Hide/show bounding boxes");
+  Msg(DIRECT, "  Alt+c         Loop through predefined color schemes");
+  Msg(DIRECT, "  Alt+f         Change redraw mode (fast/full)"); 
+  Msg(DIRECT, "  Alt+h         Hide/show all post-processing views"); 
+  Msg(DIRECT, "  Alt+i         Hide/show all post-processing view scales");
+  Msg(DIRECT, "  Alt+l         Hide/show geometry lines");
+  Msg(DIRECT, "  Alt+m         Toggle visibility of all mesh entities");
+  Msg(DIRECT, "  Alt+n         Hide/show all post-processing view annotations");
+  Msg(DIRECT, "  Alt+o         Change projection mode (orthographic/perspective)");
+  Msg(DIRECT, "  Alt+p         Hide/show geometry points");
+  Msg(DIRECT, "  Alt+s         Hide/show geometry surfaces");
+  Msg(DIRECT, "  Alt+t         Loop through interval modes for visible post-processing views"); 
+  Msg(DIRECT, "  Alt+v         Hide/show geometry volumes");
+  Msg(DIRECT, "  Alt+w         Enable/disable all lighting");
+  Msg(DIRECT, "  Alt+x         Set X view"); 
+  Msg(DIRECT, "  Alt+y         Set Y view"); 
+  Msg(DIRECT, "  Alt+z         Set Z view"); 
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  Alt+Shift+a   Hide/show small axes"); 
+  Msg(DIRECT, "  Alt+Shift+b   Hide/show mesh volume faces");
+  Msg(DIRECT, "  Alt+Shift+d   Hide/show mesh surface faces");
+  Msg(DIRECT, "  Alt+Shift+l   Hide/show mesh lines");
+  Msg(DIRECT, "  Alt+Shift+o   Adjust projection parameters");
+  Msg(DIRECT, "  Alt+Shift+p   Hide/show mesh points");
+  Msg(DIRECT, "  Alt+Shift+s   Hide/show mesh surface edges");
+  Msg(DIRECT, "  Alt+Shift+v   Hide/show mesh volume edges");
+  Msg(DIRECT, "  Alt+Shift+w   Reverse all mesh normals");
+  Msg(DIRECT, "  Alt+Shift+x   Set -X view"); 
+  Msg(DIRECT, "  Alt+Shift+y   Set -Y view"); 
+  Msg(DIRECT, "  Alt+Shift+z   Set -Z view"); 
+  Msg(DIRECT, " ");
+  WID->create_message_window();
 }
 
-void geometry_elementary_extrude_translate_cb(CALLBACK_ARGS)
+void help_mouse_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_extrude_translate, 0);
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "Mouse actions:");
+  Msg(DIRECT, " ");
+  Msg(DIRECT, "  Move                - Highlight the elementary geometrical entity");
+  Msg(DIRECT, "                        currently under the mouse pointer and display");
+  Msg(DIRECT, "                        its properties in the status bar");
+  Msg(DIRECT, "                      - Resize a lasso zoom/(un)selection");
+  Msg(DIRECT, "  Left button         - Rotate");
+  Msg(DIRECT, "                      - Select an entity");
+  Msg(DIRECT, "                      - Accept a lasso zoom/selection"); 
+  Msg(DIRECT, "  Ctrl+Left button    Start a lasso zoom/(un)selection"); 
+  Msg(DIRECT, "  Middle button       - Zoom");
+  Msg(DIRECT, "                      - Unselect an entity");
+  Msg(DIRECT, "                      - Accept a lasso zoom/unselection");
+  Msg(DIRECT, "  Ctrl+Middle button  Orthogonalize display"); 
+  Msg(DIRECT, "  Right button        - Pan");
+  Msg(DIRECT, "                      - Cancel a lasso zoom/(un)selection");
+  Msg(DIRECT, "                      - Pop-up menu on post-processing view button");
+  Msg(DIRECT, "  Ctrl+Right button   Reset to default viewpoint");   
+  Msg(DIRECT, " ");   
+  Msg(DIRECT, "  For a 2 button mouse, Middle button = Shift+Left button");
+  Msg(DIRECT, "  For a 1 button mouse, Middle button = Shift+Left button, Right button = Alt+Left button");
+  Msg(DIRECT, " ");
+  WID->create_message_window();
 }
 
-void geometry_elementary_extrude_translate_point_cb(CALLBACK_ARGS)
+void help_command_line_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(4, 0, "Point");
+  Msg(DIRECT, " ");
+  Print_Usage("gmsh");
+  WID->create_message_window();
 }
 
-void geometry_elementary_extrude_translate_line_cb(CALLBACK_ARGS)
+void help_license_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(4, 0, "Line");
+  extern void print_license();
+  Msg(DIRECT, " ");
+  print_license();
+  WID->create_message_window();
 }
 
-void geometry_elementary_extrude_translate_surface_cb(CALLBACK_ARGS)
+void help_about_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(2);
-  _action_point_line_surface_volume(4, 0, "Surface");
+  WID->create_about_window();
 }
 
-void geometry_elementary_extrude_rotate_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_geometry_elementary_extrude_rotate, 0);
+void _replace_multi_format(char *in, char *val, char *out){
+  unsigned int i = 0, j = 0;
+
+  out[0] = '\0';
+  while(i < strlen(in)){
+    if(in[i] == '%' && i != strlen(in)-1){
+      if(in[i+1] == 's'){
+	strcat(out, val);
+	i += 2;
+	j += strlen(val);
+      }
+      else{
+	Msg(WARNING, "Skipping unknown format '%%%c' in '%s'", in[i+1], in);
+	i += 2;
+      }
+    }
+    else{
+      out[j] = in[i];
+      out[j+1] = '\0';
+      i++;
+      j++;
+    }
+  }
+  out[j] = '\0';
 }
 
-void geometry_elementary_extrude_rotate_point_cb(CALLBACK_ARGS)
+void help_online_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(5, 0, "Point");
+  char prog[1024], cmd[1024];
+  FixWindowsPath(CTX.web_browser, prog);
+  _replace_multi_format(prog, "http://www.geuz.org/gmsh/doc/texinfo/", cmd);
+  SystemCall(cmd);
 }
 
-void geometry_elementary_extrude_rotate_line_cb(CALLBACK_ARGS)
+void help_credits_cb(CALLBACK_ARGS)
 {
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(5, 0, "Line");
+  char prog[1024], cmd[1024];
+  FixWindowsPath(CTX.web_browser, prog);
+  _replace_multi_format(prog, "http://www.geuz.org/gmsh/doc/CREDITS", cmd);
+  SystemCall(cmd);
 }
 
-void geometry_elementary_extrude_rotate_surface_cb(CALLBACK_ARGS)
-{
-  WID->create_geometry_context_window(3);
-  _action_point_line_surface_volume(5, 0, "Surface");
-}
+// Module Menu
 
-void geometry_elementary_coherence_cb(CALLBACK_ARGS)
+void mod_geometry_cb(CALLBACK_ARGS)
 {
-  coherence(CTX.filename);
+  WID->set_context(menu_geometry, 0);
 }
 
-void geometry_elementary_delete_cb(CALLBACK_ARGS)
+void mod_mesh_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_elementary_delete, 0);
+  WID->set_context(menu_mesh, 0);
 }
 
-void geometry_elementary_delete_point_cb(CALLBACK_ARGS)
+void mod_solver_cb(CALLBACK_ARGS)
 {
-  _action_point_line_surface_volume(6, 0, "Point");
+  WID->set_context(menu_solver, 0);
 }
 
-void geometry_elementary_delete_line_cb(CALLBACK_ARGS)
+void mod_post_cb(CALLBACK_ARGS)
 {
-  _action_point_line_surface_volume(6, 0, "Line");
+  WID->set_context(menu_post, 0);
 }
 
-void geometry_elementary_delete_surface_cb(CALLBACK_ARGS)
+void mod_back_cb(CALLBACK_ARGS)
 {
-  _action_point_line_surface_volume(6, 0, "Surface");
+  WID->set_context(NULL, -1);
 }
 
-void geometry_physical_add_cb(CALLBACK_ARGS)
+void mod_forward_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_geometry_physical_add, 0);
+  WID->set_context(NULL, 1);
 }
 
-void geometry_physical_add_point_cb(CALLBACK_ARGS)
+// Dynamic Geomtry Menus
+
+void geometry_elementary_cb(CALLBACK_ARGS)
 {
-  WID->call_for_solver_plugin(0);
-  _action_point_line_surface_volume(7, 0, "Point");
+  WID->set_context(menu_geometry_elementary, 0);
 }
 
-void geometry_physical_add_line_cb(CALLBACK_ARGS)
+void geometry_physical_cb(CALLBACK_ARGS)
 {
-  WID->call_for_solver_plugin(1);
-  _action_point_line_surface_volume(7, 0, "Line");
+  WID->set_context(menu_geometry_physical, 0);
 }
 
-void geometry_physical_add_surface_cb(CALLBACK_ARGS)
+void geometry_edit_cb(CALLBACK_ARGS)
 {
-  _action_point_line_surface_volume(7, 0, "Surface");
+  char prog[1024], file[1024], cmd[1024];
+  FixWindowsPath(CTX.editor, prog);
+  FixWindowsPath(CTX.filename, file);
+  _replace_multi_format(prog, file, cmd);
+  SystemCall(cmd);
 }
 
-void geometry_physical_add_volume_cb(CALLBACK_ARGS)
+void geometry_reload_cb(CALLBACK_ARGS)
 {
-  _action_point_line_surface_volume(7, 0, "Volume");
+  OpenProblem(CTX.filename);
+  Draw();
 }
 
-// Dynamic Mesh Menus
-
-void mesh_save_cb(CALLBACK_ARGS)
+void geometry_elementary_add_cb(CALLBACK_ARGS)
 {
-  char name[256];
-  if(CTX.output_filename)
-    strcpy(name, CTX.output_filename);
-  else
-    GetDefaultFileName(CTX.mesh.format, name);
-  if(CTX.confirm_overwrite) {
-    if(!StatFile(name))
-      if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-		    "Cancel", "Replace", NULL, name))
-	return;
-  }
-  CreateOutputFile(name, CTX.mesh.format);
+  WID->set_context(menu_geometry_elementary_add, 0);
 }
 
-void mesh_define_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_cb(CALLBACK_ARGS)
 {
-  WID->set_context(menu_mesh_define, 0);
+  WID->set_context(menu_geometry_elementary_add_new, 0);
 }
 
-void mesh_1d_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_parameter_cb(CALLBACK_ARGS)
 {
-  mai3d(1);
-  Draw();
-  Msg(STATUS2N, " ");
+  WID->create_geometry_context_window(0);
 }
 
-void mesh_2d_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_point_cb(CALLBACK_ARGS)
 {
-  mai3d(2);
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   Draw();
-  Msg(STATUS2N, " ");
+
+  WID->create_geometry_context_window(1);
+
+  while(1) {
+    WID->g_opengl_window->AddPointMode = true;
+    Msg(ONSCREEN, "Move mouse and/or enter coordinates\n"
+	"[Press 'Shift' to hold position, 'e' to add point or 'q' to abort]");
+    std::vector<GVertex*> vertices;
+    std::vector<GEdge*> edges;
+    std::vector<GFace*> faces;
+    std::vector<GRegion*> regions;
+    char ib = SelectEntity(ENT_NONE, vertices, edges, faces, regions);
+    if(ib == 'e'){
+      add_point(CTX.filename,
+		(char*)WID->context_geometry_input[2]->value(),
+		(char*)WID->context_geometry_input[3]->value(),
+		(char*)WID->context_geometry_input[4]->value(),
+		(char*)WID->context_geometry_input[5]->value());
+      WID->reset_visibility();
+      Draw();
+    }
+    if(ib == 'q'){
+      WID->g_opengl_window->AddPointMode = false;
+      break;
+    }
+  }
+
+  Msg(ONSCREEN, "");
 }
 
-void mesh_3d_cb(CALLBACK_ARGS)
+static void _new_multiline(int type)
 {
-  mai3d(3);
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  int p[100];
+
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
   Draw();
-  Msg(STATUS2N, " ");
-}
 
-void mesh_edit_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_mesh_edit, 0);
-}
+  int n = 0;
+  while(1) {
+    if(n == 0)
+      Msg(ONSCREEN, "Select control points\n"
+	  "[Press 'e' to end selection or 'q' to abort]");
+    else
+      Msg(ONSCREEN, "Select control points\n"
+	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    if(ib == 'l') {
+      for(unsigned int i = 0; i < vertices.size(); i++)
+	p[n++] = vertices[i]->tag();
+    }
+    if(ib == 'r') {
+      Msg(WARNING, "Entity de-selection not supported yet during multi-line creation");
+    }
+    if(ib == 'e') {
+      if(n >= 2) {
+        switch (type) {
+        case 0:
+          add_multline(n, p, CTX.filename);
+          break;
+        case 1:
+          add_spline(n, p, CTX.filename);
+          break;
+        case 2:
+          add_bspline(n, p, CTX.filename);
+          break;
+        case 3:
+          add_bezier(n, p, CTX.filename);
+          break;
+        }
+      }
+      WID->reset_visibility();
+      ZeroHighlight();
+      Draw();
+      n = 0;
+    }
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
+	Draw();
+	n--;
+      }
+    }
+    if(ib == 'q') {
+      ZeroHighlight();
+      Draw();
+      break;
+    }
+  }
 
-void mesh_reparam_cb(CALLBACK_ARGS)
-{
-  printf("LAUCH REPARAMETERIZATION BIGNOU HERE!\n");
+  Msg(ONSCREEN, "");
 }
 
-void mesh_degree_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
 {
-  if((long)data == 2)
-    Degre2();
-  else
-    Degre1();
-  CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
+  // Disallow multiline selection at the moment, since multilines
+  // dont't work so well...
+  //
+  //_new_multiline(0);
+  //
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  int p[100];
+
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
   Draw();
-  Msg(STATUS2N, " ");
-}
 
-void mesh_optimize_cb(CALLBACK_ARGS)
-{
-  if(CTX.threads_lock) {
-    Msg(INFO, "I'm busy! Ask me that later...");
-    return;
+  int n = 0;
+  while(1) {
+    if(n == 0)
+      Msg(ONSCREEN, "Select start point\n"
+	  "[Press 'q' to abort]");
+    if(n == 1)
+      Msg(ONSCREEN, "Select end point\n"
+	  "[Press 'u' to undo last selection or 'q' to abort]");
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    if(ib == 'l') {
+      p[n++] = vertices[0]->tag();
+    }
+    if(ib == 'r') {
+      Msg(WARNING, "Entity de-selection not supported yet during line creation");
+    }
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
+	Draw();
+	n--;
+      }
+    }
+    if(ib == 'q') {
+      ZeroHighlight();
+      Draw();
+      break;
+    }
+    if(n == 2) {
+      add_multline(2, p, CTX.filename);
+      WID->reset_visibility();
+      ZeroHighlight();
+      Draw();
+      n = 0;
+    }
   }
-  CTX.threads_lock = 1;
-  Optimize_Netgen();
-  CTX.threads_lock = 0;
 
-  CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
-  Draw();
-  Msg(STATUS2N, " ");
+  Msg(ONSCREEN, "");
 }
 
-void mesh_remesh_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_spline_cb(CALLBACK_ARGS)
 {
-  ReMesh();
-  Draw();
-  Msg(STATUS2N, " ");
+  _new_multiline(1);
 }
 
-void mesh_update_edges_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_bspline_cb(CALLBACK_ARGS)
 {
-  Msg(GERROR, "BDS->classify() must be reinterfaced");
+  _new_multiline(2);
 }
 
-void mesh_update_more_edges_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
 {
-  _action_point_line_surface_volume(10, 0, "Line");
-}
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  int p[100];
 
-void mesh_define_length_cb(CALLBACK_ARGS)
-{
-  _action_point_line_surface_volume(8, 0, "Point");
-}
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  Draw();
 
-void mesh_define_recombine_cb(CALLBACK_ARGS)
-{
-  _action_point_line_surface_volume(9, 0, "Surface");
-}
+  int n = 0;
+  while(1) {
+    if(n == 0)
+      Msg(ONSCREEN, "Select start point\n"
+	  "[Press 'q' to abort]");
+    if(n == 1)
+      Msg(ONSCREEN, "Select center point\n"
+	  "[Press 'u' to undo last selection or 'q' to abort]");
+    if(n == 2)
+      Msg(ONSCREEN, "Select end point\n"
+	  "[Press 'u' to undo last selection or 'q' to abort]");
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    if(ib == 'l') {
+      p[n++] = vertices[0]->tag();
+    }
+    if(ib == 'r') {
+      Msg(WARNING, "Entity de-selection not supported yet during circle creation");
+    }
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
+	Draw();
+	n--;
+      }
+    }
+    if(ib == 'q') {
+      ZeroHighlight();
+      Draw();
+      break;
+    }
+    if(n == 3) {
+      add_circ(p[0], p[1], p[2], CTX.filename); // begin, center, end
+      WID->reset_visibility();
+      ZeroHighlight();
+      Draw();
+      n = 0;
+    }
+  }
 
-void mesh_define_transfinite_cb(CALLBACK_ARGS)
-{
-  WID->set_context(menu_mesh_define_transfinite, 0);
+  Msg(ONSCREEN, "");
 }
 
-static void _add_transfinite_elliptic(int type, int dim)
+void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
 {
   std::vector<GVertex*> vertices;
   std::vector<GEdge*> edges;
   std::vector<GFace*> faces;
   std::vector<GRegion*> regions;
-  char ib;
   int p[100];
 
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  switch (dim) {
-  case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break;
-  case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break;
-  case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break;
-  }
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
   Draw();
 
   int n = 0;
   while(1) {
-    switch (dim) {
-    case 1:
-      if(n == 0)
-	Msg(ONSCREEN, "Select lines\n"
-	    "[Press 'e' to end selection or 'q' to abort]");
-      else
-	Msg(ONSCREEN, "Select lines\n"
-	    "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-      ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions);
-      break;
-    case 2:
-      Msg(ONSCREEN, "Select surface\n[Press 'q' to abort]");
-      ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions);
-      break;
-    case 3:
-      Msg(ONSCREEN, "Select volume\n[Press 'q' to abort]");
-      ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions);
-      break;
-    default:
-      ib = 'l';
-      break;
+    if(n == 0)
+      Msg(ONSCREEN, "Select start point\n"
+	  "[Press 'q' to abort]");
+    if(n == 1)
+      Msg(ONSCREEN, "Select center point\n"
+	  "[Press 'u' to undo last selection or 'q' to abort]");
+    if(n == 2)
+      Msg(ONSCREEN, "Select major axis point\n"
+	  "[Press 'u' to undo last selection or 'q' to abort]");
+    if(n == 3)
+      Msg(ONSCREEN, "Select end point\n"
+	  "[Press 'u' to undo last selection or 'q' to abort]");
+    char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+    if(ib == 'l') {
+      p[n++] = vertices[0]->tag();
     }
-
-    if(ib == 'e') {
-      if(dim == 1) {
-        if(n > 0)
-          add_trsfline(n, p, CTX.filename,
-		       (char*)WID->context_mesh_choice[0]->text(),
-		       (char*)WID->context_mesh_input[2]->value(),
-		       (char*)WID->context_mesh_input[1]->value());
-      }
-      ZeroHighlight();
-      Draw();
-      n = 0;
+    if(ib == 'r') {
+      Msg(WARNING, "Entity de-selection not supported yet during ellipse creation");
     }
     if(ib == 'u') {
-      if(dim == 1) {
-        if(n > 0){
-	  ZeroHighlightEntityNum(0, p[n-1], 0, 0);
-	  Draw();
-	  n--;
-	}
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
+	Draw();
+	n--;
       }
     }
     if(ib == 'q') {
@@ -2932,1245 +2707,1457 @@ static void _add_transfinite_elliptic(int type, int dim)
       Draw();
       break;
     }
-    if(ib == 'r') {
-      Msg(WARNING, "Entity de-selection not supported yet during transfinite definition");
+    if(n == 4) {
+      add_ell(p[0], p[1], p[2], p[3], CTX.filename);
+      WID->reset_visibility();
+      ZeroHighlight();
+      Draw();
+      n = 0;
     }
-    if(ib == 'l') {
-      switch (dim) {
-      case 1:
-        p[n++] = edges[0]->tag();
-        break;
-      case 2:
-      case 3:
-	if(dim == 2)
-	  p[n++] = faces[0]->tag(); 
+  }
+
+  Msg(ONSCREEN, "");
+}
+
+static void _new_surface_volume(int mode)
+{
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  int type, num;
+
+  List_T *List1 = List_Create(10, 10, sizeof(int));
+  List_T *List2 = List_Create(10, 10, sizeof(int));
+
+  if(mode == 2) {
+    type = ENT_SURFACE;
+    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else {
+    type = ENT_LINE;
+    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  Draw();
+
+  while(1) {
+    List_Reset(List1);
+    List_Reset(List2);
+
+    while(1) {
+      if(type == ENT_LINE){
+	if(!List_Nbr(List1))
+	  Msg(ONSCREEN, "Select surface boundary\n"
+	      "[Press 'q' to abort]");
 	else
-	  p[n++] = regions[0]->tag(); 
-        while(1) {
-	  if(n == 1)
-	    Msg(ONSCREEN, "Select (ordered) boundary points\n"
-		"[Press 'e' to end selection or 'q' to abort]");
-	  else
-	    Msg(ONSCREEN, "Select (ordered) boundary points\n"
-		"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
-          ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
-          if(ib == 'l') {
-            p[n++] = vertices[0]->tag();
-          }
-	  if(ib == 'u') {
-	    if(n > 1){
-	      ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
+	  Msg(ONSCREEN, "Select surface boundary\n"
+	      "[Press 'u' to undo last selection or 'q' to abort]");
+      }
+      else{
+	if(!List_Nbr(List1))
+	  Msg(ONSCREEN, "Select volume boundary\n"
+	      "[Press 'q' to abort]");
+	else
+	  Msg(ONSCREEN, "Select volume boundary\n"
+	      "[Press 'u' to undo last selection or 'q' to abort]");
+      }
+
+      char ib = SelectEntity(type, vertices, edges, faces, regions);
+      if(ib == 'q') {
+        ZeroHighlight();
+        Draw();
+        goto stopall;
+      }
+      if(ib == 'u') {
+	if(List_Nbr(List1) > 0){
+	  List_Read(List1, List_Nbr(List1)-1, &num);
+	  ZeroHighlightEntityNum(0,
+				 (type == ENT_LINE) ? abs(num) : 0, 
+				 (type != ENT_LINE) ? abs(num) : 0,
+				 0);
+	  List_Pop(List1);
+	  Draw();
+	}
+      }
+      if(ib == 'r') {
+	Msg(WARNING, "Entity de-selection not supported yet during surface/volume creation");
+      }
+      if(ib == 'l') {
+	int num = (type == ENT_LINE) ? edges[0]->tag() : faces[0]->tag();
+	if(SelectContour(type, num, List1)) {
+	  if(type == ENT_LINE)
+	    add_lineloop(List1, CTX.filename, &num);
+	  else
+	    add_surfloop(List1, CTX.filename, &num);
+	  List_Reset(List1);
+	  List_Add(List2, &num);
+	  while(1) {
+	    if(!List_Nbr(List1))
+	      Msg(ONSCREEN, "Select hole boundaries (if none, press 'e')\n"
+		  "[Press 'e' to end selection or 'q' to abort]");
+	    else
+	      Msg(ONSCREEN, "Select hole boundaries\n"
+		  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+	    ib = SelectEntity(type, vertices, edges, faces, regions);
+	    if(ib == 'q') {
+	      ZeroHighlight();
 	      Draw();
-	      n--;
+	      goto stopall;
+	    }
+	    if(ib == 'e') {
+	      ZeroHighlight();
+	      Draw();
+	      List_Reset(List1);
+	      break;
+	    }
+	    if(ib == 'u') {
+	      if(List_Nbr(List1) > 0){
+		List_Read(List1, List_Nbr(List1)-1, &num);
+		ZeroHighlightEntityNum(0,
+				       (type == ENT_LINE) ? abs(num) : 0, 
+				       (type != ENT_LINE) ? abs(num) : 0,
+				       0);
+		List_Pop(List1);
+		Draw();
+	      }
+	    }
+	    if(ib == 'l') {
+	      num = (type == ENT_LINE) ? edges[0]->tag() : faces[0]->tag();
+	      if(SelectContour(type, num, List1)) {
+		if(type == ENT_LINE)
+		  add_lineloop(List1, CTX.filename, &num);
+		else
+		  add_surfloop(List1, CTX.filename, &num);
+		List_Reset(List1);
+		List_Add(List2, &num);
+	      }
+	    }
+	    if(ib == 'r') {
+	      Msg(WARNING, "Entity de-selection not supported yet during surface/volume creation");
 	    }
 	  }
-	  if(ib == 'r') {
-	    Msg(WARNING, "Entity de-selection not supported yet during transfinite definition");
+	  if(List_Nbr(List2)) {
+	    switch (mode) {
+	    case 0: add_surf(List2, CTX.filename, 0, 2); break;
+	    case 1: add_surf(List2, CTX.filename, 0, 1); break;
+	    case 2: add_vol(List2, CTX.filename); break;
+	    }
+	    WID->reset_visibility();
+	    ZeroHighlight();
+	    Draw();
+	    break;
 	  }
-          if(ib == 'e') {
-            switch (dim) {
-            case 2:
-              if(n == 3 + 1 || n == 4 + 1)
-                add_trsfellisurf(type, n, p, CTX.filename,
-				 (char*)WID->context_mesh_choice[1]->text());
-              else
-                Msg(GERROR, "Wrong number of points for %s surface",
-		    type ? "elliptic" : "transfinite");
-              break;
-            case 3:
-              if(n == 6 + 1 || n == 8 + 1)
-                add_trsfvol(n, p, CTX.filename);
-              else
-                Msg(GERROR, "Wrong number of points for transfinite volume");
-              break;
-            }
-            ZeroHighlight();
-            Draw();
-            n = 0;
-            break;
-          }
-          if(ib == 'q') {
-            ZeroHighlight();
-            Draw();
-            goto stopall;
-          }
-        }
-        break;
+	} // if SelectContour
       }
     }
   }
 
-stopall:
-  Msg(ONSCREEN, "");
-}
+stopall:;
+  List_Delete(List1);
+  List_Delete(List2);
 
-void mesh_define_transfinite_line_cb(CALLBACK_ARGS)
-{
-  WID->create_mesh_context_window(1);
-  _add_transfinite_elliptic(0, 1);
+  Msg(ONSCREEN, "");
 }
 
-void mesh_define_transfinite_surface_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_planesurface_cb(CALLBACK_ARGS)
 {
-  WID->create_mesh_context_window(2);
-  _add_transfinite_elliptic(0, 2);
+  _new_surface_volume(0);
 }
 
-void mesh_define_transfinite_volume_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_ruledsurface_cb(CALLBACK_ARGS)
 {
-  _add_transfinite_elliptic(0, 3);
+  _new_surface_volume(1);
 }
 
-void mesh_define_elliptic_surface_cb(CALLBACK_ARGS)
+void geometry_elementary_add_new_volume_cb(CALLBACK_ARGS)
 {
-  _add_transfinite_elliptic(1, 2);
+  _new_surface_volume(2);
 }
 
-// Dynamic Solver Menus
-
-void solver_cb(CALLBACK_ARGS)
+static void _action_point_line_surface_volume(int action, int mode, char *what)
 {
-  static int init = 0, first[MAXSOLVERS];
-  int num = (int)(long)data;
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  int type;
+  char *str;
 
-  if(!init) {
-    for(int i = 0; i < MAXSOLVERS; i++)
-      first[i] = 1;
-    init = 1;
+  if(!strcmp(what, "Point")) {
+    type = ENT_POINT;
+    str = "points";
+    opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else if(!strcmp(what, "Line")) {
+    type = ENT_LINE;
+    str = "lines";
+    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else if(!strcmp(what, "Surface")) {
+    type = ENT_SURFACE;
+    str = "surfaces";
+    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else if(!strcmp(what, "Volume")) {
+    type = ENT_VOLUME;
+    str = "volumes";
+    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else{
+    Msg(GERROR, "Unknown entity to select");
+    return;
   }
 
-  if(first[num]) {
-    char file[256];
-    first[num] = 0;
-    strcpy(file, CTX.base_filename);
-    strcat(file, SINFO[num].extension);
-    WID->solver[num].input[0]->value(file);
+  if(action == 8){
+    WID->create_mesh_context_window(0);
   }
-  if(SINFO[num].nboptions) {
-    char file[256], tmp[256];
-    FixWindowsPath((char*)WID->solver[num].input[0]->value(), file);
-    sprintf(tmp, "\"%s\"", file);
-    sprintf(file, SINFO[num].name_command, tmp);
-    sprintf(tmp, "%s %s", SINFO[num].option_command, file);           
-    Solver(num, tmp);
+  else if(action == 10){
+    Msg(GERROR, "BDS->classify(angle, edge_prolongation) must be reinterfaced");
   }
-  WID->create_solver_window(num);
-}
 
-void solver_file_open_cb(CALLBACK_ARGS)
-{
-  char tmp[256];
-  int num = (int)(long)data;
-  sprintf(tmp, "*%s", SINFO[num].extension);
+  Draw();
+    
+  List_T *List1 = List_Create(5, 5, sizeof(int));
+  while(1) {
+    if(!List_Nbr(List1))
+      Msg(ONSCREEN, "Select %s\n"
+	  "[Press 'e' to end selection or 'q' to abort]", str);
+    else
+      Msg(ONSCREEN, "Select %s\n"
+	  "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
 
-  // We allow to create the .pro file... Or should we add a "New file"
-  // button?
-  if(file_chooser(0, 1, "Choose", tmp)) {
-    WID->solver[num].input[0]->value(file_chooser_get_name(1));
-    if(SINFO[num].nboptions) {
-      char file[1024];
-      FixWindowsPath(file_chooser_get_name(1), file);
-      sprintf(tmp, "\"%s\"", file);
-      sprintf(file, SINFO[num].name_command, tmp);
-      sprintf(tmp, "%s %s", SINFO[num].option_command, file);
-      Solver(num, tmp);
+    char ib = SelectEntity(type, vertices, edges, faces, regions);
+    if(ib == 'l') {
+      // we don't use List_Insert in order to keep the original
+      // ordering (this is slower, but this way undo works as
+      // expected)
+      int tag;
+      switch (type) {
+      case ENT_POINT: 
+	for(unsigned int i = 0; i < vertices.size(); i++){
+	  tag = vertices[i]->tag();
+	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+	    List_Add(List1, &tag);
+	}
+	break;
+      case ENT_LINE:
+	for(unsigned int i = 0; i < edges.size(); i++){
+	  tag = edges[i]->tag();
+	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+	    List_Add(List1, &tag);
+	}
+	break;
+      case ENT_SURFACE:
+	for(unsigned int i = 0; i < faces.size(); i++){
+	  tag = faces[i]->tag();
+	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+	    List_Add(List1, &tag);
+	}
+	break;
+      case ENT_VOLUME:
+	for(unsigned int i = 0; i < regions.size(); i++){
+	  tag = regions[i]->tag();
+	  if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+	    List_Add(List1, &tag);
+	}
+	break;
+      }
+    }
+    if(ib == 'r') {
+      // we don't use List_Suppress in order to keep the original
+      // ordering (this is slower, but this way undo works as
+      // expected)
+      int index, tag;
+      switch (type) {
+      case ENT_POINT:
+	for(unsigned int i = 0; i < vertices.size(); i++){
+	  tag = vertices[i]->tag();
+	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
+	  if(index >= 0) List_PSuppress(List1, index);
+	  ZeroHighlightEntityNum(tag, 0, 0, 0);
+	}
+	break;
+      case ENT_LINE:
+	for(unsigned int i = 0; i < edges.size(); i++){
+	  tag = edges[i]->tag();
+	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
+	  if(index >= 0) List_PSuppress(List1, index);
+	  ZeroHighlightEntityNum(0, tag, 0, 0);
+	}
+	break;
+      case ENT_SURFACE:
+	for(unsigned int i = 0; i < faces.size(); i++){
+	  tag = faces[i]->tag();
+	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
+	  if(index >= 0) List_PSuppress(List1, index);
+	  ZeroHighlightEntityNum(0, 0, tag, 0);
+	}
+	break;
+      case ENT_VOLUME:
+	for(unsigned int i = 0; i < regions.size(); i++){
+	  tag = regions[i]->tag();
+	  index = List_ISearchSeq(List1, &tag, fcmp_int); 
+	  if(index >= 0) List_PSuppress(List1, index);
+	  ZeroHighlightEntityNum(0, 0, 0, tag);
+	}
+	break;
+      }
+      Draw();
     }
-  }
-}
-
-void solver_file_edit_cb(CALLBACK_ARGS)
-{
-  char prog[1024], file[1024], cmd[1024];
-  int num = (int)(long)data;
-  FixWindowsPath(CTX.editor, prog);
-  FixWindowsPath((char*)WID->solver[num].input[0]->value(), file);
-  _replace_multi_format(prog, file, cmd);
-  SystemCall(cmd);
-}
-
-void solver_choose_mesh_cb(CALLBACK_ARGS)
-{
-  int num = (int)(long)data;
-  if(file_chooser(0, 0, "Choose", "*.msh"))
-    WID->solver[num].input[1]->value(file_chooser_get_name(1));
-}
-
-int nbs(char *str)
-{
-  int i, nb = 0;
-  for(i = 0; i < (int)strlen(str) - 1; i++) {
-    if(str[i] == '%' && str[i + 1] == 's') {
-      nb++;
-      i++;
+    if(ib == 'u') {
+      if(List_Nbr(List1)) {
+	int num;
+	List_Read(List1, List_Nbr(List1) - 1, &num);
+	ZeroHighlightEntityNum((type == ENT_POINT) ? num : 0,
+			       (type == ENT_LINE) ? num : 0,
+			       (type == ENT_SURFACE) ? num : 0,
+			       (type == ENT_VOLUME) ? num : 0);
+	Draw();
+	List_Pop(List1);
+      }
     }
-  }
-  return nb;
-}
-
-void solver_command_cb(CALLBACK_ARGS)
-{
-  char tmp[256], arg[512], mesh[256], command[256];
-  int num = ((int *)data)[0];
-  int idx = ((int *)data)[1];
-  int i, usedopts = 0;
-
-  if(SINFO[num].popup_messages)
-    WID->create_message_window(true);
-
-  if(strlen(WID->solver[num].input[1]->value())) {
-    FixWindowsPath((char*)WID->solver[num].input[1]->value(), mesh);
-    sprintf(tmp, "\"%s\"", mesh);
-    sprintf(mesh, SINFO[num].mesh_command, tmp);
-  }
-  else {
-    strcpy(mesh, "");
-  }
-
-  if(nbs(SINFO[num].button_command[idx])) {
-    for(i = 0; i < idx; i++)
-      usedopts += nbs(SINFO[num].button_command[i]);
-    if(usedopts > SINFO[num].nboptions) {
-      Msg(GERROR, "Missing options to execute command");
-      return;
+    if(ib == 'e') {
+      if(List_Nbr(List1)){
+	switch (action) {
+	case 0:
+	  translate(mode, List1, CTX.filename, what,
+		    (char*)WID->context_geometry_input[6]->value(),
+		    (char*)WID->context_geometry_input[7]->value(),
+		    (char*)WID->context_geometry_input[8]->value());
+	  break;
+	case 1:
+	  rotate(mode, List1, CTX.filename, what,
+		 (char*)WID->context_geometry_input[12]->value(),
+		 (char*)WID->context_geometry_input[13]->value(),
+		 (char*)WID->context_geometry_input[14]->value(),
+		 (char*)WID->context_geometry_input[9]->value(),
+		 (char*)WID->context_geometry_input[10]->value(),
+		 (char*)WID->context_geometry_input[11]->value(),
+		 (char*)WID->context_geometry_input[15]->value());
+	  break;
+	case 2:
+	  dilate(mode, List1, CTX.filename, what,
+		 (char*)WID->context_geometry_input[16]->value(),
+		 (char*)WID->context_geometry_input[17]->value(),
+		 (char*)WID->context_geometry_input[18]->value(),
+		 (char*)WID->context_geometry_input[19]->value());
+	  break;
+	case 3:
+	  symmetry(mode, List1, CTX.filename, what,
+		   (char*)WID->context_geometry_input[20]->value(),
+		   (char*)WID->context_geometry_input[21]->value(),
+		   (char*)WID->context_geometry_input[22]->value(),
+		   (char*)WID->context_geometry_input[23]->value());
+	  break;
+	case 4:
+	  extrude(List1, CTX.filename, what,
+		  (char*)WID->context_geometry_input[6]->value(),
+		  (char*)WID->context_geometry_input[7]->value(),
+		  (char*)WID->context_geometry_input[8]->value());
+	  break;
+	case 5:
+	  protude(List1, CTX.filename, what,
+		  (char*)WID->context_geometry_input[12]->value(),
+		  (char*)WID->context_geometry_input[13]->value(),
+		  (char*)WID->context_geometry_input[14]->value(),
+		  (char*)WID->context_geometry_input[9]->value(),
+		  (char*)WID->context_geometry_input[10]->value(),
+		  (char*)WID->context_geometry_input[11]->value(),
+		  (char*)WID->context_geometry_input[15]->value());
+	  break;
+	case 6:
+	  delet(List1, CTX.filename, what);
+	  break;
+	case 7:
+	  add_physical(List1, CTX.filename, type);
+	  break;
+	case 8:
+	  add_charlength(List1, CTX.filename, (char*)WID->context_mesh_input[0]->value());
+	  break;
+	case 9:
+	  add_recosurf(List1, CTX.filename);
+	  break;
+	case 10:
+	  Msg(GERROR, "BDS->get_geom and set status must be reinterfaced");
+	  break;
+	default:
+	  Msg(GERROR, "Unknown action on selected entities");
+	  break;
+	}
+	List_Reset(List1);
+	WID->reset_visibility();
+	ZeroHighlight();
+	if(action <= 6) SetBoundingBox();
+	Draw();
+      }
+    }
+    if(ib == 'q') {
+      if(action == 10){
+	Msg(GERROR, "BDS->classify() must be reinterfaced");
+      }
+      ZeroHighlight();
+      Draw();
+      break;
     }
-    sprintf(command, SINFO[num].button_command[idx],
-            SINFO[num].option[usedopts][WID->solver[num].choice[usedopts]->value()]);
-  }
-  else {
-    strcpy(command, SINFO[num].button_command[idx]);
-  }
-
-  FixWindowsPath((char*)WID->solver[num].input[0]->value(), tmp);
-  sprintf(arg, "\"%s\"", tmp);
-  sprintf(tmp, SINFO[num].name_command, arg);
-  sprintf(arg, "%s %s %s", tmp, mesh, command);
-  Solver(num, arg);
-}
-
-void solver_kill_cb(CALLBACK_ARGS)
-{
-  int num = (int)(long)data;
-  if(SINFO[num].pid > 0) {
-    if(KillProcess(SINFO[num].pid))
-      Msg(INFO, "Killed %s pid %d", SINFO[num].name, SINFO[num].pid);
   }
-  SINFO[num].pid = -1;
-}
+  List_Delete(List1);
 
-void solver_choose_executable_cb(CALLBACK_ARGS)
-{
-  int num = (int)(long)data;
-  if(file_chooser(0, 0, "Choose",
-#if defined(WIN32)
-                  "*.exe"
-#else
-                  "*"
-#endif
-                  ))
-    WID->solver[num].input[2]->value(file_chooser_get_name(1));
+  Msg(ONSCREEN, "");
 }
-
-void solver_ok_cb(CALLBACK_ARGS)
+  
+void geometry_elementary_add_translate_cb(CALLBACK_ARGS)
 {
-  int retry = 0, num = (int)(long)data;
-  opt_solver_popup_messages(num, GMSH_SET, WID->solver[num].butt[0]->value());
-  opt_solver_merge_views(num, GMSH_SET, WID->solver[num].butt[1]->value());
-  opt_solver_client_server(num, GMSH_SET, WID->solver[num].butt[2]->value());
-  if(strcmp(opt_solver_executable(num, GMSH_GET, NULL),
-            WID->solver[num].input[2]->value()))
-    retry = 1;
-  opt_solver_executable(num, GMSH_SET,
-                        (char *)WID->solver[num].input[2]->value());
-  if(retry)
-    solver_cb(NULL, data);
+  WID->set_context(menu_geometry_elementary_add_translate, 0);
 }
 
-// Dynamic Post Menus
-
-void view_toggle_cb(CALLBACK_ARGS)
+void geometry_elementary_add_translate_point_cb(CALLBACK_ARGS)
 {
-  int num = (int)(long)data;
-  opt_view_visible(num, GMSH_SET,
-                   WID->m_toggle_butt[num]->value());
-  Draw();
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(0, 1, "Point");
 }
 
-static void _view_reload(int num)
+void geometry_elementary_add_translate_line_cb(CALLBACK_ARGS)
 {
-  if(!CTX.post.list)
-    return;
-
-  Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, num);
-
-  if(StatFile(v->FileName)){
-    Msg(GERROR, "File '%s' does not exist", v->FileName);
-    return;
-  }
-
-  CTX.post.force_num = v->Num;
-  MergeProblem(v->FileName);
-  CTX.post.force_num = 0;
-
-  Post_View *v2 = *(Post_View **) List_Pointer(CTX.post.list, num);
-  CopyViewOptions(v, v2);
-
-  // In case the reloaded view has a different number of time steps
-  if(v2->TimeStep > v2->NbTimeStep - 1)
-    v2->TimeStep = 0;
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(0, 1, "Line");
+}
 
-  FreeView(v);
+void geometry_elementary_add_translate_surface_cb(CALLBACK_ARGS)
+{
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(0, 1, "Surface");
 }
 
-void view_reload_cb(CALLBACK_ARGS)
+void geometry_elementary_translate_cb(CALLBACK_ARGS)
 {
-  _view_reload((int)(long)data);
-  Draw();
+  WID->set_context(menu_geometry_elementary_translate, 0);
 }
 
-void view_reload_all_cb(CALLBACK_ARGS)
+void geometry_elementary_translate_point_cb(CALLBACK_ARGS)
 {
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++)
-    _view_reload(i);
-  Draw();
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(0, 0, "Point");
 }
 
-void view_reload_visible_cb(CALLBACK_ARGS)
+void geometry_elementary_translate_line_cb(CALLBACK_ARGS)
 {
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++)
-    if(opt_view_visible(i, GMSH_GET, 0))
-      _view_reload(i);
-  Draw();
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(0, 0, "Line");
 }
 
-void view_remove_other_cb(CALLBACK_ARGS)
+void geometry_elementary_translate_surface_cb(CALLBACK_ARGS)
 {
-  if(!CTX.post.list) return;
-  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
-    if(i != (long)data)
-      RemoveViewByIndex(i);
-  UpdateViewsInGUI();
-  Draw();
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(0, 0, "Surface");
 }
 
-void view_remove_all_cb(CALLBACK_ARGS)
+void geometry_elementary_add_rotate_cb(CALLBACK_ARGS)
 {
-  if(!CTX.post.list) return;
-  while(List_Nbr(CTX.post.list))
-    RemoveViewByIndex(0);
-  UpdateViewsInGUI();
-  Draw();
+  WID->set_context(menu_geometry_elementary_add_rotate, 0);
 }
 
-void view_remove_visible_cb(CALLBACK_ARGS)
+void geometry_elementary_add_rotate_point_cb(CALLBACK_ARGS)
 {
-  if(!CTX.post.list) return;
-  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
-    if(opt_view_visible(i, GMSH_GET, 0))
-      RemoveViewByIndex(i);
-  UpdateViewsInGUI();
-  Draw();
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(1, 1, "Point");
 }
 
-void view_remove_invisible_cb(CALLBACK_ARGS)
+void geometry_elementary_add_rotate_line_cb(CALLBACK_ARGS)
 {
-  if(!CTX.post.list) return;
-  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
-    if(!opt_view_visible(i, GMSH_GET, 0))
-      RemoveViewByIndex(i);
-  UpdateViewsInGUI();
-  Draw();
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(1, 1, "Line");
 }
 
-void view_remove_empty_cb(CALLBACK_ARGS)
+void geometry_elementary_add_rotate_surface_cb(CALLBACK_ARGS)
 {
-  if(!CTX.post.list) return;
-  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--){
-    Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, i);
-    if(v->empty())
-      RemoveViewByIndex(i);
-  }
-  UpdateViewsInGUI();
-  Draw();
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(1, 1, "Surface");
 }
 
-void view_remove_cb(CALLBACK_ARGS)
+void geometry_elementary_rotate_cb(CALLBACK_ARGS)
 {
-  RemoveViewByIndex((int)(long)data);
-  UpdateViewsInGUI();
-  Draw();
+  WID->set_context(menu_geometry_elementary_rotate, 0);
 }
 
-static void _view_save_as(int view_num, char *title, int type)
+void geometry_elementary_rotate_point_cb(CALLBACK_ARGS)
 {
-  Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, view_num);
-  
- test:
-  if(file_chooser(0, 1, title, "*", v->FileName)) {
-    char *name = file_chooser_get_name(1);
-    if(CTX.confirm_overwrite) {
-      if(!StatFile(name))
-        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-		      "Cancel", "Replace", NULL, name))
-          goto test;
-    }
-    WriteView(v, name, type, 0);
-  }
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(1, 0, "Point");
 }
 
-void view_save_ascii_cb(CALLBACK_ARGS)
+void geometry_elementary_rotate_line_cb(CALLBACK_ARGS)
 {
-  _view_save_as((int)(long)data, "Save As ASCII View", 0);
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(1, 0, "Line");
 }
 
-void view_save_binary_cb(CALLBACK_ARGS)
+void geometry_elementary_rotate_surface_cb(CALLBACK_ARGS)
 {
-  _view_save_as((int)(long)data, "Save As Binary View", 1);
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(1, 0, "Surface");
 }
 
-void view_save_parsed_cb(CALLBACK_ARGS)
+void geometry_elementary_add_scale_cb(CALLBACK_ARGS)
 {
-  _view_save_as((int)(long)data, "Save As Parsed View", 2);
+  WID->set_context(menu_geometry_elementary_add_scale, 0);
 }
 
-void view_save_stl_cb(CALLBACK_ARGS)
+void geometry_elementary_add_scale_point_cb(CALLBACK_ARGS)
 {
-  _view_save_as((int)(long)data, "Save As STL Triangulation", 3);
+  WID->create_geometry_context_window(4);
+  _action_point_line_surface_volume(2, 1, "Point");
 }
 
-void view_save_txt_cb(CALLBACK_ARGS)
+void geometry_elementary_add_scale_line_cb(CALLBACK_ARGS)
 {
-  _view_save_as((int)(long)data, "Save As Text", 4);
+  WID->create_geometry_context_window(4);
+  _action_point_line_surface_volume(2, 1, "Line");
 }
 
-void view_save_msh_cb(CALLBACK_ARGS)
+void geometry_elementary_add_scale_surface_cb(CALLBACK_ARGS)
 {
-  _view_save_as((int)(long)data, "Save As Mesh", 5);
+  WID->create_geometry_context_window(4);
+  _action_point_line_surface_volume(2, 1, "Surface");
 }
 
-void view_alias_cb(CALLBACK_ARGS)
+void geometry_elementary_scale_cb(CALLBACK_ARGS)
 {
-  AliasView((int)(long)data, 0);
-  Draw();
+  WID->set_context(menu_geometry_elementary_scale, 0);
 }
 
-void view_alias_with_options_cb(CALLBACK_ARGS)
+void geometry_elementary_scale_point_cb(CALLBACK_ARGS)
 {
-  AliasView((int)(long)data, 1);
-  Draw();
+  WID->create_geometry_context_window(4);
+  _action_point_line_surface_volume(2, 0, "Point");
 }
 
-void view_combine_space_all_cb(CALLBACK_ARGS)
+void geometry_elementary_scale_line_cb(CALLBACK_ARGS)
 {
-  CombineViews(0, 1, CTX.post.combine_remove_orig);
-  Draw();
+  WID->create_geometry_context_window(4);
+  _action_point_line_surface_volume(2, 0, "Line");
 }
 
-void view_combine_space_visible_cb(CALLBACK_ARGS)
+void geometry_elementary_scale_surface_cb(CALLBACK_ARGS)
 {
-  CombineViews(0, 0, CTX.post.combine_remove_orig);
-  Draw();
+  WID->create_geometry_context_window(4);
+  _action_point_line_surface_volume(2, 0, "Surface");
 }
 
-void view_combine_space_by_name_cb(CALLBACK_ARGS)
+void geometry_elementary_add_symmetry_cb(CALLBACK_ARGS)
 {
-  CombineViews(0, 2, CTX.post.combine_remove_orig);
-  Draw();
+  WID->set_context(menu_geometry_elementary_add_symmetry, 0);
 }
 
-void view_combine_time_all_cb(CALLBACK_ARGS)
+void geometry_elementary_add_symmetry_point_cb(CALLBACK_ARGS)
 {
-  CombineViews(1, 1, CTX.post.combine_remove_orig);
-  Draw();
+  WID->create_geometry_context_window(5);
+  _action_point_line_surface_volume(3, 1, "Point");
 }
 
-void view_combine_time_visible_cb(CALLBACK_ARGS)
+void geometry_elementary_add_symmetry_line_cb(CALLBACK_ARGS)
 {
-  CombineViews(1, 0, CTX.post.combine_remove_orig);
-  Draw();
+  WID->create_geometry_context_window(5);
+  _action_point_line_surface_volume(3, 1, "Line");
 }
 
-void view_combine_time_by_name_cb(CALLBACK_ARGS)
+void geometry_elementary_add_symmetry_surface_cb(CALLBACK_ARGS)
 {
-  CombineViews(1, 2, CTX.post.combine_remove_orig);
-  Draw();
+  WID->create_geometry_context_window(5);
+  _action_point_line_surface_volume(3, 1, "Surface");
 }
 
-void view_all_visible_cb(CALLBACK_ARGS)
+void geometry_elementary_symmetry_cb(CALLBACK_ARGS)
 {
-  for(int i = 0; i < List_Nbr(CTX.post.list); i ++)
-    opt_view_visible(i, GMSH_SET | GMSH_GUI, 
-		     (long)data < 0 ? !opt_view_visible(i, GMSH_GET, 0) :
-		     (long)data > 0 ? 1 : 0);
-  Draw();
+  WID->set_context(menu_geometry_elementary_symmetry, 0);
 }
 
-void view_applybgmesh_cb(CALLBACK_ARGS)
+void geometry_elementary_symmetry_point_cb(CALLBACK_ARGS)
 {
-  Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, (int)(long)data);
-  if(!v->ScalarOnly || v->TextOnly) {
-    Msg(GERROR, "Background mesh generation impossible with non-scalar view");
-    return;
-  }
-  BGMWithView(v);
+  WID->create_geometry_context_window(5);
+  _action_point_line_surface_volume(3, 0, "Point");
 }
 
-void view_options_cb(CALLBACK_ARGS)
+void geometry_elementary_symmetry_line_cb(CALLBACK_ARGS)
 {
-  WID->create_view_options_window((int)(long)data);
+  WID->create_geometry_context_window(5);
+  _action_point_line_surface_volume(3, 0, "Line");
 }
 
-void view_plugin_cancel_cb(CALLBACK_ARGS)
+void geometry_elementary_symmetry_surface_cb(CALLBACK_ARGS)
 {
-  if(data)
-    ((Fl_Window *) data)->hide();
-  if(CTX.post.plugin_draw_function){
-    CTX.post.plugin_draw_function = NULL;
-    Draw();
-  }
+  WID->create_geometry_context_window(5);
+  _action_point_line_surface_volume(3, 0, "Surface");
 }
 
-void view_plugin_run_cb(CALLBACK_ARGS)
+void geometry_elementary_extrude_cb(CALLBACK_ARGS)
 {
-  GMSH_Post_Plugin *p = (GMSH_Post_Plugin *) data;
-  char name[256];
-  p->getName(name);
-  int iView;
+  WID->set_context(menu_geometry_elementary_extrude, 0);
+}
 
-  if(p->dialogBox) { // get the values from the GUI
-    iView = p->dialogBox->current_view_index;
-    int m = p->getNbOptionsStr();
-    int n = p->getNbOptions();
-    if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
-    if(n > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
-    for(int i = 0; i < m; i++) {
-      StringXString *sxs = p->getOptionStr(i);
-      sxs->def = (char*)p->dialogBox->input[i]->value();
-    }
-    for(int i = 0; i < n; i++) {
-      StringXNumber *sxn = p->getOption(i);
-      sxn->def = p->dialogBox->value[i]->value();
-    }
-  }
-  else
-    iView = 0;
+void geometry_elementary_extrude_translate_cb(CALLBACK_ARGS)
+{
+  WID->set_context(menu_geometry_elementary_extrude_translate, 0);
+}
 
-  try {
-    Post_View **vv = (Post_View **) List_Pointer_Test(CTX.post.list, iView);
-    if(!vv)
-      p->execute(0);
-    else
-      p->execute(*vv);
-    CTX.post.plugin_draw_function = NULL;
-    Draw();
-  }
-  catch(GMSH_Plugin * err) {
-    p->catchErrorMessage(name);
-    Msg(WARNING, "%s", name);
-  }
+void geometry_elementary_extrude_translate_point_cb(CALLBACK_ARGS)
+{
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(4, 0, "Point");
+}
+
+void geometry_elementary_extrude_translate_line_cb(CALLBACK_ARGS)
+{
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(4, 0, "Line");
 }
 
-void view_plugin_input_value_cb(CALLBACK_ARGS)
+void geometry_elementary_extrude_translate_surface_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());
+  WID->create_geometry_context_window(2);
+  _action_point_line_surface_volume(4, 0, "Surface");
 }
 
-void view_plugin_input_cb(CALLBACK_ARGS)
+void geometry_elementary_extrude_rotate_cb(CALLBACK_ARGS)
 {
-  char* (*f)(int, int, char*) = (char* (*)(int, int, char*)) data;
-  Fl_Input *input = (Fl_Input*) w;
-  f(-1, 0, (char*)input->value());
+  WID->set_context(menu_geometry_elementary_extrude_rotate, 0);
 }
 
-void view_plugin_options_cb(CALLBACK_ARGS)
+void geometry_elementary_extrude_rotate_point_cb(CALLBACK_ARGS)
 {
-  std::pair<int, GMSH_Plugin *> *pair = (std::pair<int, GMSH_Plugin *>*) data;
-  int iView = pair->first;
-  GMSH_Plugin *p = pair->second;
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(5, 0, "Point");
+}
 
-  if(!p->dialogBox)
-    p->dialogBox = WID->create_plugin_window(p);
+void geometry_elementary_extrude_rotate_line_cb(CALLBACK_ARGS)
+{
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(5, 0, "Line");
+}
 
-  p->dialogBox->current_view_index = iView;
-  p->dialogBox->run_button->callback(view_plugin_run_cb, (void *)p);
+void geometry_elementary_extrude_rotate_surface_cb(CALLBACK_ARGS)
+{
+  WID->create_geometry_context_window(3);
+  _action_point_line_surface_volume(5, 0, "Surface");
+}
 
-  // configure the input value 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 > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
-  for(int i = 0; i < n; i++) {
-    StringXNumber *sxn = p->getOption(i);
-    if(sxn->function){
-      p->dialogBox->value[i]->callback(view_plugin_input_value_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.));
-    }
-  }
+void geometry_elementary_coherence_cb(CALLBACK_ARGS)
+{
+  coherence(CTX.filename);
+}
 
-  // set the Fl_Input callbacks
-  int m = p->getNbOptionsStr();
-  if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
-  for(int i = 0; i < m; i++) {
-    StringXString *sxs = p->getOptionStr(i);
-    if(sxs->function){
-      p->dialogBox->input[i]->callback(view_plugin_input_cb, (void*)sxs->function);
-    }
-  }
+void geometry_elementary_delete_cb(CALLBACK_ARGS)
+{
+  WID->set_context(menu_geometry_elementary_delete, 0);
+}
 
-  p->dialogBox->main_window->show();
+void geometry_elementary_delete_point_cb(CALLBACK_ARGS)
+{
+  _action_point_line_surface_volume(6, 0, "Point");
 }
 
-void view_options_timestep_cb(CALLBACK_ARGS)
+void geometry_elementary_delete_line_cb(CALLBACK_ARGS)
 {
-  int links = (int)opt_post_link(0, GMSH_GET, 0);
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
-    if((links == 2 || links == 4) ||
-       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == WID->view_number)) {
-      opt_view_timestep(i, GMSH_SET, ((Fl_Value_Input *) w)->value());
-    }
-  }
-  Draw();
+  _action_point_line_surface_volume(6, 0, "Line");
 }
 
-void view_options_timestep_decr_cb(CALLBACK_ARGS)
+void geometry_elementary_delete_surface_cb(CALLBACK_ARGS)
 {
-  int links = (int)opt_post_link(0, GMSH_GET, 0);
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
-    if((links == 2 || links == 4) ||
-       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == WID->view_number)) {
-      opt_view_timestep(i, GMSH_SET | GMSH_GUI,
-                        opt_view_timestep(i, GMSH_GET, 0) - 1);
-    }
-  }
-  Draw();
+  _action_point_line_surface_volume(6, 0, "Surface");
 }
 
-void view_options_timestep_incr_cb(CALLBACK_ARGS)
+void geometry_physical_add_cb(CALLBACK_ARGS)
 {
-  int links = (int)opt_post_link(0, GMSH_GET, 0);
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
-    if((links == 2 || links == 4) ||
-       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == WID->view_number)) {
-      opt_view_timestep(i, GMSH_SET | GMSH_GUI,
-                        opt_view_timestep(i, GMSH_GET, 0) + 1);
-    }
-  }
-  Draw();
+  WID->set_context(menu_geometry_physical_add, 0);
 }
 
-void view_options_custom_set_cb(CALLBACK_ARGS)
+void geometry_physical_add_point_cb(CALLBACK_ARGS)
 {
-  char *str = (char*)data;
+  WID->call_for_solver_plugin(0);
+  _action_point_line_surface_volume(7, 0, "Point");
+}
 
-  if(!strcmp(str, "Min")){
-    WID->view_value[31]->value(opt_view_min(WID->view_number, GMSH_GET, 0));
-  }
-  else if(!strcmp(str, "Max")){
-    WID->view_value[32]->value(opt_view_max(WID->view_number, GMSH_GET, 0));
-  }
+void geometry_physical_add_line_cb(CALLBACK_ARGS)
+{
+  WID->call_for_solver_plugin(1);
+  _action_point_line_surface_volume(7, 0, "Line");
 }
 
-void view_options_ok_cb(CALLBACK_ARGS)
+void geometry_physical_add_surface_cb(CALLBACK_ARGS)
 {
-  int current = (int)(long)data;
+  _action_point_line_surface_volume(7, 0, "Surface");
+}
 
-  if(current < 0)
-    return;
+void geometry_physical_add_volume_cb(CALLBACK_ARGS)
+{
+  _action_point_line_surface_volume(7, 0, "Volume");
+}
 
-  int force = 0, links = (int)opt_post_link(0, GMSH_GET, 0);
+// Dynamic Mesh Menus
 
-  // get the old values for the current view
+void mesh_save_cb(CALLBACK_ARGS)
+{
+  char name[256];
+  if(CTX.output_filename)
+    strcpy(name, CTX.output_filename);
+  else
+    GetDefaultFileName(CTX.mesh.format, name);
+  if(CTX.confirm_overwrite) {
+    if(!StatFile(name))
+      if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
+		    "Cancel", "Replace", NULL, name))
+	return;
+  }
+  CreateOutputFile(name, CTX.mesh.format);
+}
 
-  double scale_type = opt_view_scale_type(current, GMSH_GET, 0);
-  double intervals_type = opt_view_intervals_type(current, GMSH_GET, 0);
-  double point_type = opt_view_point_type(current, GMSH_GET, 0);
-  double line_type = opt_view_line_type(current, GMSH_GET, 0);
-  double vector_type = opt_view_vector_type(current, GMSH_GET, 0);
-  double glyph_location = opt_view_glyph_location(current, GMSH_GET, 0);
-  double tensor_type = opt_view_tensor_type(current, GMSH_GET, 0);
-  double range_type = opt_view_range_type(current, GMSH_GET, 0);
-  double axes = opt_view_axes(current, GMSH_GET, 0);
-  double boundary = opt_view_boundary(current, GMSH_GET, 0);
-  double external_view = opt_view_external_view(current, GMSH_GET, 0);
-  double gen_raise_view = opt_view_gen_raise_view(current, GMSH_GET, 0);
-  double show_time = opt_view_show_time(current, GMSH_GET, 0);
+void mesh_define_cb(CALLBACK_ARGS)
+{
+  WID->set_context(menu_mesh_define, 0);
+}
 
-  double type = opt_view_type(current, GMSH_GET, 0);
-  double saturate_values = opt_view_saturate_values(current, GMSH_GET, 0);
-  double max_recursion_level = opt_view_max_recursion_level(current, GMSH_GET, 0);
-  double target_error = opt_view_target_error(current, GMSH_GET, 0);
-  double show_element = opt_view_show_element(current, GMSH_GET, 0);
-  double show_scale = opt_view_show_scale(current, GMSH_GET, 0);
-  double auto_position = opt_view_auto_position(current, GMSH_GET, 0);
-  double axes_auto_position = opt_view_axes_auto_position(current, GMSH_GET, 0);
-  double draw_strings = opt_view_draw_strings(current, GMSH_GET, 0);
-  double light = opt_view_light(current, GMSH_GET, 0);
-  double light_two_side = opt_view_light_two_side(current, GMSH_GET, 0);
-  double light_lines = opt_view_light_lines(current, GMSH_GET, 0);
-  double smooth_normals = opt_view_smooth_normals(current, GMSH_GET, 0);
-  double draw_points = opt_view_draw_points(current, GMSH_GET, 0);
-  double draw_lines = opt_view_draw_lines(current, GMSH_GET, 0);
-  double draw_triangles = opt_view_draw_triangles(current, GMSH_GET, 0);
-  double draw_quadrangles = opt_view_draw_quadrangles(current, GMSH_GET, 0);
-  double draw_tetrahedra = opt_view_draw_tetrahedra(current, GMSH_GET, 0);
-  double draw_hexahedra = opt_view_draw_hexahedra(current, GMSH_GET, 0);
-  double draw_prisms = opt_view_draw_prisms(current, GMSH_GET, 0);
-  double draw_pyramids = opt_view_draw_pyramids(current, GMSH_GET, 0);
-  double draw_scalars = opt_view_draw_scalars(current, GMSH_GET, 0);
-  double draw_vectors = opt_view_draw_vectors(current, GMSH_GET, 0);
-  double draw_tensors = opt_view_draw_tensors(current, GMSH_GET, 0);
-  double use_gen_raise = opt_view_use_gen_raise(current, GMSH_GET, 0);
-  double fake_transparency = opt_view_fake_transparency(current, GMSH_GET, 0);
-  double use_stipple = opt_view_use_stipple(current, GMSH_GET, 0);
+void mesh_1d_cb(CALLBACK_ARGS)
+{
+  mai3d(1);
+  Draw();
+  Msg(STATUS2N, " ");
+}
 
-  double normals = opt_view_normals(current, GMSH_GET, 0);
-  double tangents = opt_view_tangents(current, GMSH_GET, 0);
-  double custom_min = opt_view_custom_min(current, GMSH_GET, 0);
-  double custom_max = opt_view_custom_max(current, GMSH_GET, 0);
-  double nb_iso = opt_view_nb_iso(current, GMSH_GET, 0);
-  double offset0 = opt_view_offset0(current, GMSH_GET, 0);
-  double offset1 = opt_view_offset1(current, GMSH_GET, 0);
-  double offset2 = opt_view_offset2(current, GMSH_GET, 0);
-  double transform00 = opt_view_transform00(current, GMSH_GET, 0);
-  double transform01 = opt_view_transform01(current, GMSH_GET, 0);
-  double transform02 = opt_view_transform02(current, GMSH_GET, 0);
-  double transform10 = opt_view_transform10(current, GMSH_GET, 0);
-  double transform11 = opt_view_transform11(current, GMSH_GET, 0);
-  double transform12 = opt_view_transform12(current, GMSH_GET, 0);
-  double transform20 = opt_view_transform20(current, GMSH_GET, 0);
-  double transform21 = opt_view_transform21(current, GMSH_GET, 0);
-  double transform22 = opt_view_transform22(current, GMSH_GET, 0);
-  double raise0 = opt_view_raise0(current, GMSH_GET, 0);
-  double raise1 = opt_view_raise1(current, GMSH_GET, 0);
-  double raise2 = opt_view_raise2(current, GMSH_GET, 0);
-  double timestep = opt_view_timestep(current, GMSH_GET, 0);
-  double arrow_size = opt_view_arrow_size(current, GMSH_GET, 0);
-  double arrow_size_proportional = opt_view_arrow_size_proportional(current, GMSH_GET, 0);
-  double displacement_factor = opt_view_displacement_factor(current, GMSH_GET, 0);
-  double point_size = opt_view_point_size(current, GMSH_GET, 0);
-  double line_width = opt_view_line_width(current, GMSH_GET, 0);
-  double explode = opt_view_explode(current, GMSH_GET, 0);
-  double angle_smooth_normals = opt_view_angle_smooth_normals(current, GMSH_GET, 0);
-  double position0 = opt_view_position0(current, GMSH_GET, 0);
-  double position1 = opt_view_position1(current, GMSH_GET, 0);
-  double size0 = opt_view_size0(current, GMSH_GET, 0);
-  double size1 = opt_view_size1(current, GMSH_GET, 0);
-  double axes_tics0 = opt_view_axes_tics0(current, GMSH_GET, 0);
-  double axes_tics1 = opt_view_axes_tics1(current, GMSH_GET, 0);
-  double axes_tics2 = opt_view_axes_tics2(current, GMSH_GET, 0);
-  double axes_xmin = opt_view_axes_xmin(current, GMSH_GET, 0);
-  double axes_ymin = opt_view_axes_ymin(current, GMSH_GET, 0);
-  double axes_zmin = opt_view_axes_zmin(current, GMSH_GET, 0);
-  double axes_xmax = opt_view_axes_xmax(current, GMSH_GET, 0);
-  double axes_ymax = opt_view_axes_ymax(current, GMSH_GET, 0);
-  double axes_zmax = opt_view_axes_zmax(current, GMSH_GET, 0);
-  double gen_raise_factor = opt_view_gen_raise_factor(current, GMSH_GET, 0);
+void mesh_2d_cb(CALLBACK_ARGS)
+{
+  mai3d(2);
+  Draw();
+  Msg(STATUS2N, " ");
+}
 
-  char name[256];
-  strcpy(name, opt_view_name(current, GMSH_GET, NULL));
-  char format[256];
-  strcpy(format, opt_view_format(current, GMSH_GET, NULL));
-  char axes_label0[256];
-  strcpy(axes_label0, opt_view_axes_label0(current, GMSH_GET, NULL));
-  char axes_label1[256];
-  strcpy(axes_label1, opt_view_axes_label1(current, GMSH_GET, NULL));
-  char axes_label2[256];
-  strcpy(axes_label2, opt_view_axes_label2(current, GMSH_GET, NULL));
-  char axes_format0[256];
-  strcpy(axes_format0, opt_view_axes_format0(current, GMSH_GET, NULL));
-  char axes_format1[256];
-  strcpy(axes_format1, opt_view_axes_format1(current, GMSH_GET, NULL));
-  char axes_format2[256];
-  strcpy(axes_format2, opt_view_axes_format2(current, GMSH_GET, NULL));
-  char gen_raise0[256];
-  strcpy(gen_raise0, opt_view_gen_raise0(current, GMSH_GET, NULL));
-  char gen_raise1[256];
-  strcpy(gen_raise1, opt_view_gen_raise1(current, GMSH_GET, NULL));
-  char gen_raise2[256];
-  strcpy(gen_raise2, opt_view_gen_raise2(current, GMSH_GET, NULL));
+void mesh_3d_cb(CALLBACK_ARGS)
+{
+  mai3d(3);
+  Draw();
+  Msg(STATUS2N, " ");
+}
 
-  // modify only the views that need to be updated
-  for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
-    if((links == 2 || links == 4) ||
-       ((links == 1 || links == 3) && opt_view_visible(i, GMSH_GET, 0)) ||
-       (links == 0 && i == current)) {
+void mesh_edit_cb(CALLBACK_ARGS)
+{
+  WID->set_context(menu_mesh_edit, 0);
+}
 
-      if(links == 3 || links == 4)
-        force = 1;
+void mesh_reparam_cb(CALLBACK_ARGS)
+{
+  printf("LAUCH REPARAMETERIZATION BIGNOU HERE!\n");
+}
 
-      double val;
+void mesh_degree_cb(CALLBACK_ARGS)
+{
+  if((long)data == 2)
+    Degre2();
+  else
+    Degre1();
+  CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
+  Draw();
+  Msg(STATUS2N, " ");
+}
 
-      // view_choice
+void mesh_optimize_cb(CALLBACK_ARGS)
+{
+  if(CTX.threads_lock) {
+    Msg(INFO, "I'm busy! Ask me that later...");
+    return;
+  }
+  CTX.threads_lock = 1;
+  Optimize_Netgen();
+  CTX.threads_lock = 0;
 
-      switch (WID->view_choice[1]->value()) {
-      case 0: val = DRAW_POST_LINEAR; break;
-      case 1: val = DRAW_POST_LOGARITHMIC; break;
-      default: val = DRAW_POST_DOUBLELOGARITHMIC; break; // 2
-      }
-      if(force || (val != scale_type))
-        opt_view_scale_type(i, GMSH_SET, val);
+  CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
+  Draw();
+  Msg(STATUS2N, " ");
+}
 
-      switch (WID->view_choice[0]->value()) {
-      case 0: val = DRAW_POST_ISO; break;
-      case 1: val = DRAW_POST_DISCRETE; break;
-      case 2: val = DRAW_POST_CONTINUOUS; break;
-      default: val = DRAW_POST_NUMERIC; break; // 3
-      }
-      if(force || (val != intervals_type))
-	opt_view_intervals_type(i, GMSH_SET, val);
-      
-      val = WID->view_choice[5]->value();
-      if(force || (val != point_type))
-	opt_view_point_type(i, GMSH_SET, val);
-      
-      val = WID->view_choice[6]->value();
-      if(force || (val != line_type))
-        opt_view_line_type(i, GMSH_SET, val);
+void mesh_remesh_cb(CALLBACK_ARGS)
+{
+  ReMesh();
+  Draw();
+  Msg(STATUS2N, " ");
+}
 
-      switch (WID->view_choice[2]->value()) {
-      case 0: val = DRAW_POST_SEGMENT; break;
-      case 1: val = DRAW_POST_ARROW; break;
-      case 2: val = DRAW_POST_PYRAMID; break;
-      case 4: val = DRAW_POST_DISPLACEMENT; break;
-      default: val = DRAW_POST_ARROW3D; break; // 3
-      }
-      if(force || (val != vector_type))
-        opt_view_vector_type(i, GMSH_SET, val);
+void mesh_update_edges_cb(CALLBACK_ARGS)
+{
+  Msg(GERROR, "BDS->classify() must be reinterfaced");
+}
 
-      switch (WID->view_choice[3]->value()) {
-      case 0: val = DRAW_POST_LOCATE_COG; break;
-      default: val = DRAW_POST_LOCATE_VERTEX; break;
-      }
-      if(force || (val != glyph_location))
-        opt_view_glyph_location(i, GMSH_SET, val);
+void mesh_update_more_edges_cb(CALLBACK_ARGS)
+{
+  _action_point_line_surface_volume(10, 0, "Line");
+}
 
-     switch (WID->view_choice[4]->value()) {
-     case 0: val = DRAW_POST_VONMISES; break;
-     case 2: val = DRAW_POST_LMGC90_TYPE; break;
-     case 3: val = DRAW_POST_LMGC90_COORD; break;
-     case 4: val = DRAW_POST_LMGC90_PRES; break;
-     case 5: val = DRAW_POST_LMGC90_SN; break;
-     case 6: val = DRAW_POST_LMGC90_DEPX; break;
-     case 7: val = DRAW_POST_LMGC90_DEPY; break;
-     case 8: val = DRAW_POST_LMGC90_DEPZ; break;
-     case 9: val = DRAW_POST_LMGC90_DEPAV; break;
-     case 10: val = DRAW_POST_LMGC90_DEPNORM; break;
-     default: val = DRAW_POST_LMGC90; break; // 1
-     }
-     if(force || (val != tensor_type))
-       opt_view_tensor_type(i, GMSH_SET, val);
+void mesh_define_length_cb(CALLBACK_ARGS)
+{
+  _action_point_line_surface_volume(8, 0, "Point");
+}
 
-      switch (WID->view_choice[7]->value()) {
-      case 0: val = DRAW_POST_RANGE_DEFAULT; break;
-      case 1: val = DRAW_POST_RANGE_PER_STEP; break;
-      default: val = DRAW_POST_RANGE_CUSTOM; break; // 2
-      }
-      if(force || (val != range_type))
-        opt_view_range_type(i, GMSH_SET, val);
+void mesh_define_recombine_cb(CALLBACK_ARGS)
+{
+  _action_point_line_surface_volume(9, 0, "Surface");
+}
 
-      val = WID->view_choice[8]->value();
-      if(force || (val != axes))
-        opt_view_axes(i, GMSH_SET, val);
+void mesh_define_transfinite_cb(CALLBACK_ARGS)
+{
+  WID->set_context(menu_mesh_define_transfinite, 0);
+}
 
-      val = WID->view_choice[9]->value();
-      if(force || (val != boundary))
-        opt_view_boundary(i, GMSH_SET, val);
+static void _add_transfinite_elliptic(int type, int dim)
+{
+  std::vector<GVertex*> vertices;
+  std::vector<GEdge*> edges;
+  std::vector<GFace*> faces;
+  std::vector<GRegion*> regions;
+  char ib;
+  int p[100];
 
-      val = WID->view_choice[10]->value() - 1;
-      if(force || (val != external_view))
-        opt_view_external_view(i, GMSH_SET, val);
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  switch (dim) {
+  case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break;
+  case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break;
+  case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break;
+  }
+  Draw();
 
-      val = WID->view_choice[11]->value() - 1;
-      if(force || (val != gen_raise_view))
-        opt_view_gen_raise_view(i, GMSH_SET, val);
+  int n = 0;
+  while(1) {
+    switch (dim) {
+    case 1:
+      if(n == 0)
+	Msg(ONSCREEN, "Select lines\n"
+	    "[Press 'e' to end selection or 'q' to abort]");
+      else
+	Msg(ONSCREEN, "Select lines\n"
+	    "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+      ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions);
+      break;
+    case 2:
+      Msg(ONSCREEN, "Select surface\n[Press 'q' to abort]");
+      ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions);
+      break;
+    case 3:
+      Msg(ONSCREEN, "Select volume\n[Press 'q' to abort]");
+      ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions);
+      break;
+    default:
+      ib = 'l';
+      break;
+    }
 
-      val = WID->view_choice[12]->value();
-      if(force || (val != show_time))
-        opt_view_show_time(i, GMSH_SET, val);
-      
-      switch(WID->view_choice[13]->value()){
-      case 0: val = DRAW_POST_3D; break;
-      case 1: val = DRAW_POST_2D_SPACE; break;
-      default: val = DRAW_POST_2D_TIME; break; // 2
+    if(ib == 'e') {
+      if(dim == 1) {
+        if(n > 0)
+          add_trsfline(n, p, CTX.filename,
+		       (char*)WID->context_mesh_choice[0]->text(),
+		       (char*)WID->context_mesh_input[2]->value(),
+		       (char*)WID->context_mesh_input[1]->value());
+      }
+      ZeroHighlight();
+      Draw();
+      n = 0;
+    }
+    if(ib == 'u') {
+      if(dim == 1) {
+        if(n > 0){
+	  ZeroHighlightEntityNum(0, p[n-1], 0, 0);
+	  Draw();
+	  n--;
+	}
+      }
+    }
+    if(ib == 'q') {
+      ZeroHighlight();
+      Draw();
+      break;
+    }
+    if(ib == 'r') {
+      Msg(WARNING, "Entity de-selection not supported yet during transfinite definition");
+    }
+    if(ib == 'l') {
+      switch (dim) {
+      case 1:
+        p[n++] = edges[0]->tag();
+        break;
+      case 2:
+      case 3:
+	if(dim == 2)
+	  p[n++] = faces[0]->tag(); 
+	else
+	  p[n++] = regions[0]->tag(); 
+        while(1) {
+	  if(n == 1)
+	    Msg(ONSCREEN, "Select (ordered) boundary points\n"
+		"[Press 'e' to end selection or 'q' to abort]");
+	  else
+	    Msg(ONSCREEN, "Select (ordered) boundary points\n"
+		"[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+          ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions);
+          if(ib == 'l') {
+            p[n++] = vertices[0]->tag();
+          }
+	  if(ib == 'u') {
+	    if(n > 1){
+	      ZeroHighlightEntityNum(p[n-1], 0, 0, 0);
+	      Draw();
+	      n--;
+	    }
+	  }
+	  if(ib == 'r') {
+	    Msg(WARNING, "Entity de-selection not supported yet during transfinite definition");
+	  }
+          if(ib == 'e') {
+            switch (dim) {
+            case 2:
+              if(n == 3 + 1 || n == 4 + 1)
+                add_trsfellisurf(type, n, p, CTX.filename,
+				 (char*)WID->context_mesh_choice[1]->text());
+              else
+                Msg(GERROR, "Wrong number of points for %s surface",
+		    type ? "elliptic" : "transfinite");
+              break;
+            case 3:
+              if(n == 6 + 1 || n == 8 + 1)
+                add_trsfvol(n, p, CTX.filename);
+              else
+                Msg(GERROR, "Wrong number of points for transfinite volume");
+              break;
+            }
+            ZeroHighlight();
+            Draw();
+            n = 0;
+            break;
+          }
+          if(ib == 'q') {
+            ZeroHighlight();
+            Draw();
+            goto stopall;
+          }
+        }
+        break;
       }
-      if(force || (val != type))
-        opt_view_type(i, GMSH_SET, val);
-
-      // view_butts
-
-      val = WID->view_butt[0]->value();
-      if(force || (val != arrow_size_proportional))
-        opt_view_arrow_size_proportional(i, GMSH_SET, val);
-
-      val = WID->view_butt[38]->value();
-      if(force || (val != saturate_values))
-        opt_view_saturate_values(i, GMSH_SET, val);
-
-      val = WID->view_butt[10]->value();
-      if(force || (val != show_element))
-        opt_view_show_element(i, GMSH_SET, val);
-
-      val = WID->view_butt[4]->value();
-      if(force || (val != show_scale))
-        opt_view_show_scale(i, GMSH_SET, val);
-
-      val = WID->view_butt[7]->value();
-      if(force || (val != auto_position))
-        opt_view_auto_position(i, GMSH_SET, val);
-
-      val = WID->view_butt[25]->value();
-      if(force || (val != axes_auto_position))
-        opt_view_axes_auto_position(i, GMSH_SET, val);
-
-      val = WID->view_butt[5]->value();
-      if(force || (val != draw_strings))
-        opt_view_draw_strings(i, GMSH_SET, val);
-
-      val = WID->view_butt[11]->value();
-      if(force || (val != light))
-        opt_view_light(i, GMSH_SET, val);
-
-      val = WID->view_butt[8]->value();
-      if(force || (val != light_lines))
-        opt_view_light_lines(i, GMSH_SET, val);
-
-      val = WID->view_butt[9]->value();
-      if(force || (val != light_two_side))
-        opt_view_light_two_side(i, GMSH_SET, val);
-
-      val = WID->view_butt[12]->value();
-      if(force || (val != smooth_normals))
-        opt_view_smooth_normals(i, GMSH_SET, val);
-
-      val = WID->view_menu_butt[0]->menu()[0].value() ? 1 : 0;
-      if(force || (val != draw_scalars))
-        opt_view_draw_scalars(i, GMSH_SET, val);
-
-      val = WID->view_menu_butt[0]->menu()[1].value() ? 1 : 0;
-      if(force || (val != draw_vectors))
-        opt_view_draw_vectors(i, GMSH_SET, val);
-
-      val = WID->view_menu_butt[0]->menu()[2].value() ? 1 : 0;
-      if(force || (val != draw_tensors))
-        opt_view_draw_tensors(i, GMSH_SET, val);
-
-      val = WID->view_menu_butt[1]->menu()[0].value() ? 1 : 0;
-      if(force || (val != draw_points))
-        opt_view_draw_points(i, GMSH_SET, val);
-
-      val = WID->view_menu_butt[1]->menu()[1].value() ? 1 : 0;
-      if(force || (val != draw_lines))
-        opt_view_draw_lines(i, GMSH_SET, val);
-
-      val = WID->view_menu_butt[1]->menu()[2].value() ? 1 : 0;
-      if(force || (val != draw_triangles))
-        opt_view_draw_triangles(i, GMSH_SET, val);
+    }
+  }
 
-      val = WID->view_menu_butt[1]->menu()[3].value() ? 1 : 0;
-      if(force || (val != draw_quadrangles))
-        opt_view_draw_quadrangles(i, GMSH_SET, val);
+stopall:
+  Msg(ONSCREEN, "");
+}
 
-      val = WID->view_menu_butt[1]->menu()[4].value() ? 1 : 0;
-      if(force || (val != draw_tetrahedra))
-        opt_view_draw_tetrahedra(i, GMSH_SET, val);
+void mesh_define_transfinite_line_cb(CALLBACK_ARGS)
+{
+  WID->create_mesh_context_window(1);
+  _add_transfinite_elliptic(0, 1);
+}
 
-      val = WID->view_menu_butt[1]->menu()[5].value() ? 1 : 0;
-      if(force || (val != draw_hexahedra))
-        opt_view_draw_hexahedra(i, GMSH_SET, val);
+void mesh_define_transfinite_surface_cb(CALLBACK_ARGS)
+{
+  WID->create_mesh_context_window(2);
+  _add_transfinite_elliptic(0, 2);
+}
 
-      val = WID->view_menu_butt[1]->menu()[6].value() ? 1 : 0;
-      if(force || (val != draw_prisms))
-        opt_view_draw_prisms(i, GMSH_SET, val);
+void mesh_define_transfinite_volume_cb(CALLBACK_ARGS)
+{
+  _add_transfinite_elliptic(0, 3);
+}
 
-      val = WID->view_menu_butt[1]->menu()[7].value() ? 1 : 0;
-      if(force || (val != draw_pyramids))
-        opt_view_draw_pyramids(i, GMSH_SET, val);
+void mesh_define_elliptic_surface_cb(CALLBACK_ARGS)
+{
+  _add_transfinite_elliptic(1, 2);
+}
 
-      val = WID->view_butt[6]->value();
-      if(force || (val != use_gen_raise))
-        opt_view_use_gen_raise(i, GMSH_SET, val);
+// Dynamic Solver Menus
 
-      val = WID->view_butt[24]->value();
-      if(force || (val != fake_transparency))
-        opt_view_fake_transparency(i, GMSH_SET, val);
+void solver_cb(CALLBACK_ARGS)
+{
+  static int init = 0, first[MAXSOLVERS];
+  int num = (int)(long)data;
 
-      val = WID->view_butt[26]->value();
-      if(force || (val != use_stipple))
-        opt_view_use_stipple(i, GMSH_SET, val);
+  if(!init) {
+    for(int i = 0; i < MAXSOLVERS; i++)
+      first[i] = 1;
+    init = 1;
+  }
 
-      // view_values
-      
-      val = WID->view_value[0]->value();
-      if(force || (val != normals))
-        opt_view_normals(i, GMSH_SET, val);
+  if(first[num]) {
+    char file[256];
+    first[num] = 0;
+    strcpy(file, CTX.base_filename);
+    strcat(file, SINFO[num].extension);
+    WID->solver[num].input[0]->value(file);
+  }
+  if(SINFO[num].nboptions) {
+    char file[256], tmp[256];
+    FixWindowsPath((char*)WID->solver[num].input[0]->value(), file);
+    sprintf(tmp, "\"%s\"", file);
+    sprintf(file, SINFO[num].name_command, tmp);
+    sprintf(tmp, "%s %s", SINFO[num].option_command, file);           
+    Solver(num, tmp);
+  }
+  WID->create_solver_window(num);
+}
 
-      val = WID->view_value[1]->value();
-      if(force || (val != tangents))
-        opt_view_tangents(i, GMSH_SET, val);
+void solver_file_open_cb(CALLBACK_ARGS)
+{
+  char tmp[256];
+  int num = (int)(long)data;
+  sprintf(tmp, "*%s", SINFO[num].extension);
 
-      val = WID->view_value[31]->value();
-      if(force || (val != custom_min))
-        opt_view_custom_min(i, GMSH_SET, val);
+  // We allow to create the .pro file... Or should we add a "New file"
+  // button?
+  if(file_chooser(0, 1, "Choose", tmp)) {
+    WID->solver[num].input[0]->value(file_chooser_get_name(1));
+    if(SINFO[num].nboptions) {
+      char file[1024];
+      FixWindowsPath(file_chooser_get_name(1), file);
+      sprintf(tmp, "\"%s\"", file);
+      sprintf(file, SINFO[num].name_command, tmp);
+      sprintf(tmp, "%s %s", SINFO[num].option_command, file);
+      Solver(num, tmp);
+    }
+  }
+}
 
-      val = WID->view_value[32]->value();
-      if(force || (val != custom_max))
-        opt_view_custom_max(i, GMSH_SET, val);
+void solver_file_edit_cb(CALLBACK_ARGS)
+{
+  char prog[1024], file[1024], cmd[1024];
+  int num = (int)(long)data;
+  FixWindowsPath(CTX.editor, prog);
+  FixWindowsPath((char*)WID->solver[num].input[0]->value(), file);
+  _replace_multi_format(prog, file, cmd);
+  SystemCall(cmd);
+}
 
-      val = WID->view_value[33]->value();
-      if(force || (val != max_recursion_level))
-        opt_view_max_recursion_level(i, GMSH_SET, val);
+void solver_choose_mesh_cb(CALLBACK_ARGS)
+{
+  int num = (int)(long)data;
+  if(file_chooser(0, 0, "Choose", "*.msh"))
+    WID->solver[num].input[1]->value(file_chooser_get_name(1));
+}
 
-      val = WID->view_value[34]->value();
-      if(force || (val != target_error))
-        opt_view_target_error(i, GMSH_SET, val);
+int nbs(char *str)
+{
+  int i, nb = 0;
+  for(i = 0; i < (int)strlen(str) - 1; i++) {
+    if(str[i] == '%' && str[i + 1] == 's') {
+      nb++;
+      i++;
+    }
+  }
+  return nb;
+}
 
-      val = WID->view_value[30]->value();
-      if(force || (val != nb_iso))
-        opt_view_nb_iso(i, GMSH_SET, val);
+void solver_command_cb(CALLBACK_ARGS)
+{
+  char tmp[256], arg[512], mesh[256], command[256];
+  int num = ((int *)data)[0];
+  int idx = ((int *)data)[1];
+  int i, usedopts = 0;
 
-      val = WID->view_value[40]->value();
-      if(force || (val != offset0))
-        opt_view_offset0(i, GMSH_SET, val);
+  if(SINFO[num].popup_messages)
+    WID->create_message_window(true);
 
-      val = WID->view_value[41]->value();
-      if(force || (val != offset1))
-        opt_view_offset1(i, GMSH_SET, val);
+  if(strlen(WID->solver[num].input[1]->value())) {
+    FixWindowsPath((char*)WID->solver[num].input[1]->value(), mesh);
+    sprintf(tmp, "\"%s\"", mesh);
+    sprintf(mesh, SINFO[num].mesh_command, tmp);
+  }
+  else {
+    strcpy(mesh, "");
+  }
 
-      val = WID->view_value[42]->value();
-      if(force || (val != offset2))
-        opt_view_offset2(i, GMSH_SET, val);
+  if(nbs(SINFO[num].button_command[idx])) {
+    for(i = 0; i < idx; i++)
+      usedopts += nbs(SINFO[num].button_command[i]);
+    if(usedopts > SINFO[num].nboptions) {
+      Msg(GERROR, "Missing options to execute command");
+      return;
+    }
+    sprintf(command, SINFO[num].button_command[idx],
+            SINFO[num].option[usedopts][WID->solver[num].choice[usedopts]->value()]);
+  }
+  else {
+    strcpy(command, SINFO[num].button_command[idx]);
+  }
 
-      val = WID->view_value[51]->value();
-      if(force || (val != transform00))
-        opt_view_transform00(i, GMSH_SET, val);
+  FixWindowsPath((char*)WID->solver[num].input[0]->value(), tmp);
+  sprintf(arg, "\"%s\"", tmp);
+  sprintf(tmp, SINFO[num].name_command, arg);
+  sprintf(arg, "%s %s %s", tmp, mesh, command);
+  Solver(num, arg);
+}
 
-      val = WID->view_value[52]->value();
-      if(force || (val != transform01))
-        opt_view_transform01(i, GMSH_SET, val);
+void solver_kill_cb(CALLBACK_ARGS)
+{
+  int num = (int)(long)data;
+  if(SINFO[num].pid > 0) {
+    if(KillProcess(SINFO[num].pid))
+      Msg(INFO, "Killed %s pid %d", SINFO[num].name, SINFO[num].pid);
+  }
+  SINFO[num].pid = -1;
+}
 
-      val = WID->view_value[53]->value();
-      if(force || (val != transform02))
-        opt_view_transform02(i, GMSH_SET, val);
+void solver_choose_executable_cb(CALLBACK_ARGS)
+{
+  int num = (int)(long)data;
+  if(file_chooser(0, 0, "Choose",
+#if defined(WIN32)
+                  "*.exe"
+#else
+                  "*"
+#endif
+                  ))
+    WID->solver[num].input[2]->value(file_chooser_get_name(1));
+}
 
-      val = WID->view_value[54]->value();
-      if(force || (val != transform10))
-        opt_view_transform10(i, GMSH_SET, val);
+void solver_ok_cb(CALLBACK_ARGS)
+{
+  int retry = 0, num = (int)(long)data;
+  opt_solver_popup_messages(num, GMSH_SET, WID->solver[num].butt[0]->value());
+  opt_solver_merge_views(num, GMSH_SET, WID->solver[num].butt[1]->value());
+  opt_solver_client_server(num, GMSH_SET, WID->solver[num].butt[2]->value());
+  if(strcmp(opt_solver_executable(num, GMSH_GET, NULL),
+            WID->solver[num].input[2]->value()))
+    retry = 1;
+  opt_solver_executable(num, GMSH_SET,
+                        (char *)WID->solver[num].input[2]->value());
+  if(retry)
+    solver_cb(NULL, data);
+}
 
-      val = WID->view_value[55]->value();
-      if(force || (val != transform11))
-        opt_view_transform11(i, GMSH_SET, val);
+// Dynamic Post Menus
 
-      val = WID->view_value[56]->value();
-      if(force || (val != transform12))
-        opt_view_transform12(i, GMSH_SET, val);
+void view_toggle_cb(CALLBACK_ARGS)
+{
+  int num = (int)(long)data;
+  opt_view_visible(num, GMSH_SET,
+                   WID->m_toggle_butt[num]->value());
+  Draw();
+}
 
-      val = WID->view_value[57]->value();
-      if(force || (val != transform20))
-        opt_view_transform20(i, GMSH_SET, val);
+static void _view_reload(int num)
+{
+  if(!CTX.post.list)
+    return;
 
-      val = WID->view_value[58]->value();
-      if(force || (val != transform21))
-        opt_view_transform21(i, GMSH_SET, val);
+  Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, num);
 
-      val = WID->view_value[59]->value();
-      if(force || (val != transform22))
-        opt_view_transform22(i, GMSH_SET, val);
+  if(StatFile(v->FileName)){
+    Msg(GERROR, "File '%s' does not exist", v->FileName);
+    return;
+  }
 
-      val = WID->view_value[43]->value();
-      if(force || (val != raise0))
-        opt_view_raise0(i, GMSH_SET, val);
+  CTX.post.force_num = v->Num;
+  MergeProblem(v->FileName);
+  CTX.post.force_num = 0;
 
-      val = WID->view_value[44]->value();
-      if(force || (val != raise1))
-        opt_view_raise1(i, GMSH_SET, val);
+  Post_View *v2 = *(Post_View **) List_Pointer(CTX.post.list, num);
+  CopyViewOptions(v, v2);
 
-      val = WID->view_value[45]->value();
-      if(force || (val != raise2))
-        opt_view_raise2(i, GMSH_SET, val);
+  // In case the reloaded view has a different number of time steps
+  if(v2->TimeStep > v2->NbTimeStep - 1)
+    v2->TimeStep = 0;
 
-      val = WID->view_value[50]->value();
-      if(force || (val != timestep))
-        opt_view_timestep(i, GMSH_SET, val);
+  FreeView(v);
+}
 
-      val = WID->view_value[60]->value();
-      if(force || (val != arrow_size))
-        opt_view_arrow_size(i, GMSH_SET, val);
+void view_reload_cb(CALLBACK_ARGS)
+{
+  _view_reload((int)(long)data);
+  Draw();
+}
 
-      val = WID->view_value[63]->value();
-      if(force || (val != displacement_factor))
-        opt_view_displacement_factor(i, GMSH_SET, val);
+void view_reload_all_cb(CALLBACK_ARGS)
+{
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++)
+    _view_reload(i);
+  Draw();
+}
 
-      val = WID->view_value[61]->value();
-      if(force || (val != point_size))
-        opt_view_point_size(i, GMSH_SET, val);
+void view_reload_visible_cb(CALLBACK_ARGS)
+{
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++)
+    if(opt_view_visible(i, GMSH_GET, 0))
+      _view_reload(i);
+  Draw();
+}
 
-      val = WID->view_value[62]->value();
-      if(force || (val != line_width))
-        opt_view_line_width(i, GMSH_SET, val);
+void view_remove_other_cb(CALLBACK_ARGS)
+{
+  if(!CTX.post.list) return;
+  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
+    if(i != (long)data)
+      RemoveViewByIndex(i);
+  UpdateViewsInGUI();
+  Draw();
+}
 
-      val = WID->view_value[12]->value();
-      if(force || (val != explode))
-        opt_view_explode(i, GMSH_SET, val);
+void view_remove_all_cb(CALLBACK_ARGS)
+{
+  if(!CTX.post.list) return;
+  while(List_Nbr(CTX.post.list))
+    RemoveViewByIndex(0);
+  UpdateViewsInGUI();
+  Draw();
+}
 
-      val = WID->view_value[10]->value();
-      if(force || (val != angle_smooth_normals))
-        opt_view_angle_smooth_normals(i, GMSH_SET, val);
+void view_remove_visible_cb(CALLBACK_ARGS)
+{
+  if(!CTX.post.list) return;
+  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
+    if(opt_view_visible(i, GMSH_GET, 0))
+      RemoveViewByIndex(i);
+  UpdateViewsInGUI();
+  Draw();
+}
 
-      val = WID->view_value[20]->value();
-      if(force || (val != position0))
-        opt_view_position0(i, GMSH_SET, val);
+void view_remove_invisible_cb(CALLBACK_ARGS)
+{
+  if(!CTX.post.list) return;
+  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--)
+    if(!opt_view_visible(i, GMSH_GET, 0))
+      RemoveViewByIndex(i);
+  UpdateViewsInGUI();
+  Draw();
+}
 
-      val = WID->view_value[21]->value();
-      if(force || (val != position1))
-        opt_view_position1(i, GMSH_SET, val);
+void view_remove_empty_cb(CALLBACK_ARGS)
+{
+  if(!CTX.post.list) return;
+  for(int i = List_Nbr(CTX.post.list) - 1; i >= 0; i--){
+    Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, i);
+    if(v->empty())
+      RemoveViewByIndex(i);
+  }
+  UpdateViewsInGUI();
+  Draw();
+}
 
-      val = WID->view_value[22]->value();
-      if(force || (val != size0))
-        opt_view_size0(i, GMSH_SET, val);
-      
-      val = WID->view_value[23]->value();
-      if(force || (val != size1))
-        opt_view_size1(i, GMSH_SET, val);
+void view_remove_cb(CALLBACK_ARGS)
+{
+  RemoveViewByIndex((int)(long)data);
+  UpdateViewsInGUI();
+  Draw();
+}
 
-      val = WID->view_value[13]->value();
-      if(force || (val != axes_xmin))
-        opt_view_axes_xmin(i, GMSH_SET, val);
+static void _view_save_as(int view_num, char *title, int type)
+{
+  Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, view_num);
+  
+ test:
+  if(file_chooser(0, 1, title, "*", v->FileName)) {
+    char *name = file_chooser_get_name(1);
+    if(CTX.confirm_overwrite) {
+      if(!StatFile(name))
+        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
+		      "Cancel", "Replace", NULL, name))
+          goto test;
+    }
+    WriteView(v, name, type, 0);
+  }
+}
 
-      val = WID->view_value[14]->value();
-      if(force || (val != axes_ymin))
-        opt_view_axes_ymin(i, GMSH_SET, val);
+void view_save_ascii_cb(CALLBACK_ARGS)
+{
+  _view_save_as((int)(long)data, "Save As ASCII View", 0);
+}
 
-      val = WID->view_value[15]->value();
-      if(force || (val != axes_zmin))
-        opt_view_axes_zmin(i, GMSH_SET, val);
+void view_save_binary_cb(CALLBACK_ARGS)
+{
+  _view_save_as((int)(long)data, "Save As Binary View", 1);
+}
 
-      val = WID->view_value[16]->value();
-      if(force || (val != axes_xmax))
-        opt_view_axes_xmax(i, GMSH_SET, val);
+void view_save_parsed_cb(CALLBACK_ARGS)
+{
+  _view_save_as((int)(long)data, "Save As Parsed View", 2);
+}
 
-      val = WID->view_value[17]->value();
-      if(force || (val != axes_ymax))
-        opt_view_axes_ymax(i, GMSH_SET, val);
+void view_save_stl_cb(CALLBACK_ARGS)
+{
+  _view_save_as((int)(long)data, "Save As STL Triangulation", 3);
+}
 
-      val = WID->view_value[18]->value();
-      if(force || (val != axes_zmax))
-        opt_view_axes_zmax(i, GMSH_SET, val);
+void view_save_txt_cb(CALLBACK_ARGS)
+{
+  _view_save_as((int)(long)data, "Save As Text", 4);
+}
 
-      val = WID->view_value[2]->value();
-      if(force || (val != gen_raise_factor))
-        opt_view_gen_raise_factor(i, GMSH_SET, val);
+void view_save_msh_cb(CALLBACK_ARGS)
+{
+  _view_save_as((int)(long)data, "Save As Mesh", 5);
+}
 
-      val = WID->view_value[3]->value();
-      if(force || (val != axes_tics0))
-        opt_view_axes_tics0(i, GMSH_SET, val);
+void view_alias_cb(CALLBACK_ARGS)
+{
+  AliasView((int)(long)data, 0);
+  Draw();
+}
 
-      val = WID->view_value[4]->value();
-      if(force || (val != axes_tics1))
-        opt_view_axes_tics1(i, GMSH_SET, val);
+void view_alias_with_options_cb(CALLBACK_ARGS)
+{
+  AliasView((int)(long)data, 1);
+  Draw();
+}
 
-      val = WID->view_value[5]->value();
-      if(force || (val != axes_tics2))
-        opt_view_axes_tics2(i, GMSH_SET, val);
+void view_combine_space_all_cb(CALLBACK_ARGS)
+{
+  CombineViews(0, 1, CTX.post.combine_remove_orig);
+  Draw();
+}
 
-      // view_inputs
+void view_combine_space_visible_cb(CALLBACK_ARGS)
+{
+  CombineViews(0, 0, CTX.post.combine_remove_orig);
+  Draw();
+}
 
-      char *str;
+void view_combine_space_by_name_cb(CALLBACK_ARGS)
+{
+  CombineViews(0, 2, CTX.post.combine_remove_orig);
+  Draw();
+}
 
-      str = (char *)WID->view_input[0]->value();
-      if(force || strcmp(str, name))
-        opt_view_name(i, GMSH_SET, str);
+void view_combine_time_all_cb(CALLBACK_ARGS)
+{
+  CombineViews(1, 1, CTX.post.combine_remove_orig);
+  Draw();
+}
 
-      str = (char *)WID->view_input[1]->value();
-      if(force || strcmp(str, format))
-        opt_view_format(i, GMSH_SET, str);
+void view_combine_time_visible_cb(CALLBACK_ARGS)
+{
+  CombineViews(1, 0, CTX.post.combine_remove_orig);
+  Draw();
+}
 
-      str = (char *)WID->view_input[10]->value();
-      if(force || strcmp(str, axes_label0))
-        opt_view_axes_label0(i, GMSH_SET, str);
+void view_combine_time_by_name_cb(CALLBACK_ARGS)
+{
+  CombineViews(1, 2, CTX.post.combine_remove_orig);
+  Draw();
+}
 
-      str = (char *)WID->view_input[11]->value();
-      if(force || strcmp(str, axes_label1))
-        opt_view_axes_label1(i, GMSH_SET, str);
+void view_all_visible_cb(CALLBACK_ARGS)
+{
+  for(int i = 0; i < List_Nbr(CTX.post.list); i ++)
+    opt_view_visible(i, GMSH_SET | GMSH_GUI, 
+		     (long)data < 0 ? !opt_view_visible(i, GMSH_GET, 0) :
+		     (long)data > 0 ? 1 : 0);
+  Draw();
+}
 
-      str = (char *)WID->view_input[12]->value();
-      if(force || strcmp(str, axes_label2))
-        opt_view_axes_label2(i, GMSH_SET, str);
+void view_applybgmesh_cb(CALLBACK_ARGS)
+{
+  Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, (int)(long)data);
+  if(!v->ScalarOnly || v->TextOnly) {
+    Msg(GERROR, "Background mesh generation impossible with non-scalar view");
+    return;
+  }
+  BGMWithView(v);
+}
 
-      str = (char *)WID->view_input[7]->value();
-      if(force || strcmp(str, axes_format0))
-        opt_view_axes_format0(i, GMSH_SET, str);
+void view_plugin_cancel_cb(CALLBACK_ARGS)
+{
+  if(data)
+    ((Fl_Window *) data)->hide();
+  if(CTX.post.plugin_draw_function){
+    CTX.post.plugin_draw_function = NULL;
+    Draw();
+  }
+}
 
-      str = (char *)WID->view_input[8]->value();
-      if(force || strcmp(str, axes_format1))
-        opt_view_axes_format1(i, GMSH_SET, str);
+void view_plugin_run_cb(CALLBACK_ARGS)
+{
+  GMSH_Post_Plugin *p = (GMSH_Post_Plugin *) data;
+  char name[256];
+  p->getName(name);
+  int iView;
 
-      str = (char *)WID->view_input[9]->value();
-      if(force || strcmp(str, axes_format2))
-        opt_view_axes_format2(i, GMSH_SET, str);
+  if(p->dialogBox) { // get the values from the GUI
+    iView = p->dialogBox->current_view_index;
+    int m = p->getNbOptionsStr();
+    int n = p->getNbOptions();
+    if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
+    if(n > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
+    for(int i = 0; i < m; i++) {
+      StringXString *sxs = p->getOptionStr(i);
+      sxs->def = (char*)p->dialogBox->input[i]->value();
+    }
+    for(int i = 0; i < n; i++) {
+      StringXNumber *sxn = p->getOption(i);
+      sxn->def = p->dialogBox->value[i]->value();
+    }
+  }
+  else
+    iView = 0;
 
-      str = (char *)WID->view_input[4]->value();
-      if(force || strcmp(str, gen_raise0))
-        opt_view_gen_raise0(i, GMSH_SET, str);
+  try {
+    Post_View **vv = (Post_View **) List_Pointer_Test(CTX.post.list, iView);
+    if(!vv)
+      p->execute(0);
+    else
+      p->execute(*vv);
+    CTX.post.plugin_draw_function = NULL;
+    Draw();
+  }
+  catch(GMSH_Plugin * err) {
+    p->catchErrorMessage(name);
+    Msg(WARNING, "%s", name);
+  }
+}
 
-      str = (char *)WID->view_input[5]->value();
-      if(force || strcmp(str, gen_raise1))
-        opt_view_gen_raise1(i, GMSH_SET, str);
+void view_plugin_input_value_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());
+}
 
-      str = (char *)WID->view_input[6]->value();
-      if(force || strcmp(str, gen_raise2))
-        opt_view_gen_raise2(i, GMSH_SET, str);
+void view_plugin_input_cb(CALLBACK_ARGS)
+{
+  char* (*f)(int, int, char*) = (char* (*)(int, int, char*)) data;
+  Fl_Input *input = (Fl_Input*) w;
+  f(-1, 0, (char*)input->value());
+}
 
-      // colors (since the color buttons modify the values directly
-      // through callbacks, we can use the opt_XXX routines directly)
-      if(force || (i != current)){
-        opt_view_color_points(i, GMSH_SET, opt_view_color_points(current, GMSH_GET, 0));
-	opt_view_color_lines(i, GMSH_SET, opt_view_color_lines(current, GMSH_GET, 0));
-	opt_view_color_triangles(i, GMSH_SET, opt_view_color_triangles(current, GMSH_GET, 0));
-	opt_view_color_quadrangles(i, GMSH_SET, opt_view_color_quadrangles(current, GMSH_GET, 0));
-        opt_view_color_tetrahedra(i, GMSH_SET, opt_view_color_tetrahedra(current, GMSH_GET, 0));
-        opt_view_color_hexahedra(i, GMSH_SET, opt_view_color_hexahedra(current, GMSH_GET, 0));
-        opt_view_color_prisms(i, GMSH_SET, opt_view_color_prisms(current, GMSH_GET, 0));
-        opt_view_color_pyramids(i, GMSH_SET, opt_view_color_pyramids(current, GMSH_GET, 0));
-        opt_view_color_tangents(i, GMSH_SET, opt_view_color_tangents(current, GMSH_GET, 0));
-        opt_view_color_normals(i, GMSH_SET, opt_view_color_normals(current, GMSH_GET, 0));
-        opt_view_color_text2d(i, GMSH_SET, opt_view_color_text2d(current, GMSH_GET, 0));
-        opt_view_color_text3d(i, GMSH_SET, opt_view_color_text3d(current, GMSH_GET, 0));
-        opt_view_color_axes(i, GMSH_SET, opt_view_color_axes(current, GMSH_GET, 0));
-      }
+void view_plugin_options_cb(CALLBACK_ARGS)
+{
+  std::pair<int, GMSH_Plugin *> *pair = (std::pair<int, GMSH_Plugin *>*) data;
+  int iView = pair->first;
+  GMSH_Plugin *p = pair->second;
 
-      // colorbar window
+  if(!p->dialogBox)
+    p->dialogBox = WID->create_plugin_window(p);
 
-      if(force || (WID->view_colorbar_window->changed() && i != current)) {
-	Post_View *src = *(Post_View **)List_Pointer(CTX.post.list, current);
-	Post_View *dest = *(Post_View **)List_Pointer(CTX.post.list, i);
-        ColorTable_Copy(&src->CT);
-        ColorTable_Paste(&dest->CT);
-	dest->Changed = 1;
-      }
+  p->dialogBox->current_view_index = iView;
+  p->dialogBox->run_button->callback(view_plugin_run_cb, (void *)p);
+
+  // configure the input value 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 > MAX_PLUGIN_OPTIONS) n = MAX_PLUGIN_OPTIONS;
+  for(int i = 0; i < n; i++) {
+    StringXNumber *sxn = p->getOption(i);
+    if(sxn->function){
+      p->dialogBox->value[i]->callback(view_plugin_input_value_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.));
     }
   }
 
-  // clear the changed flag on the colorbar
-  WID->view_colorbar_window->clear_changed();
-}
-
-void view_arrow_param_cb(CALLBACK_ARGS)
-{
-  double a = opt_view_arrow_head_radius(WID->view_number, GMSH_GET, 0);
-  double b = opt_view_arrow_stem_length(WID->view_number, GMSH_GET, 0);
-  double c = opt_view_arrow_stem_radius(WID->view_number, GMSH_GET, 0);
-  while(arrow_editor("Arrow Editor", a, b, c)){
-    opt_view_arrow_head_radius(WID->view_number, GMSH_SET, a);
-    opt_view_arrow_stem_length(WID->view_number, GMSH_SET, b);
-    opt_view_arrow_stem_radius(WID->view_number, GMSH_SET, c);
-    Draw();
+  // set the Fl_Input callbacks
+  int m = p->getNbOptionsStr();
+  if(m > MAX_PLUGIN_OPTIONS) m = MAX_PLUGIN_OPTIONS;
+  for(int i = 0; i < m; i++) {
+    StringXString *sxs = p->getOptionStr(i);
+    if(sxs->function){
+      p->dialogBox->input[i]->callback(view_plugin_input_cb, (void*)sxs->function);
+    }
   }
+
+  p->dialogBox->main_window->show();
 }
 
 // Contextual windows for geometry
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 9520226c6c..64bcbc61f5 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -81,13 +81,11 @@ void options_cb(CALLBACK_ARGS);
 void options_browser_cb(CALLBACK_ARGS);
 void options_save_cb(CALLBACK_ARGS);
 void options_restore_defaults_cb(CALLBACK_ARGS);
-void options_ok_cb(CALLBACK_ARGS);
 
 void general_options_cb(CALLBACK_ARGS);
+void general_options_ok_cb(CALLBACK_ARGS);
 void general_options_color_scheme_cb(CALLBACK_ARGS);
 void general_options_rotation_center_select_cb(CALLBACK_ARGS);
-void general_options_light_cb(CALLBACK_ARGS);
-void general_options_ok_cb(CALLBACK_ARGS);
 void general_arrow_param_cb(CALLBACK_ARGS);
 
 void geometry_options_cb(CALLBACK_ARGS);
@@ -95,8 +93,6 @@ void geometry_options_ok_cb(CALLBACK_ARGS);
 
 void mesh_options_cb(CALLBACK_ARGS);
 void mesh_options_ok_cb(CALLBACK_ARGS);
-void mesh_cut_plane_cb(CALLBACK_ARGS);
-void mesh_cut_plane_invert_cb(CALLBACK_ARGS);
 
 void solver_options_cb(CALLBACK_ARGS);
 void solver_options_ok_cb(CALLBACK_ARGS);
@@ -104,6 +100,12 @@ void solver_options_ok_cb(CALLBACK_ARGS);
 void post_options_cb(CALLBACK_ARGS);
 void post_options_ok_cb(CALLBACK_ARGS);
 
+void view_options_cb(CALLBACK_ARGS);
+void view_options_ok_cb(CALLBACK_ARGS);
+void view_options_timestep_cb(CALLBACK_ARGS);
+void view_options_timestep_decr_cb(CALLBACK_ARGS);
+void view_options_timestep_incr_cb(CALLBACK_ARGS);
+void view_arrow_param_cb(CALLBACK_ARGS);
 void view_toggle_cb(CALLBACK_ARGS);
 void view_reload_cb(CALLBACK_ARGS);
 void view_reload_all_cb(CALLBACK_ARGS);
@@ -132,13 +134,6 @@ void view_all_visible_cb(CALLBACK_ARGS);
 void view_applybgmesh_cb(CALLBACK_ARGS);
 void view_plugin_options_cb(CALLBACK_ARGS);
 void view_plugin_cancel_cb(CALLBACK_ARGS);
-void view_options_cb(CALLBACK_ARGS);
-void view_options_timestep_cb(CALLBACK_ARGS);
-void view_options_timestep_decr_cb(CALLBACK_ARGS);
-void view_options_timestep_incr_cb(CALLBACK_ARGS);
-void view_options_custom_set_cb(CALLBACK_ARGS);
-void view_options_ok_cb(CALLBACK_ARGS);
-void view_arrow_param_cb(CALLBACK_ARGS);
 
 // Statistics Menu
 
diff --git a/Fltk/Colorbar_Window.cpp b/Fltk/Colorbar_Window.cpp
index e4a506ca85..57fe0b9318 100644
--- a/Fltk/Colorbar_Window.cpp
+++ b/Fltk/Colorbar_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Colorbar_Window.cpp,v 1.50 2006-01-06 00:34:22 geuzaine Exp $
+// $Id: Colorbar_Window.cpp,v 1.51 2006-08-26 17:00:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -544,8 +544,9 @@ int Colorbar_Window::handle(int event)
       ColorTable_Recompute(ct);
       draw();
       *viewchanged = 1;
-      set_changed();
     }
+
+    if(*viewchanged) do_callback();
     return 1;
 
   case FL_PUSH:
@@ -613,12 +614,7 @@ int Colorbar_Window::handle(int event)
     else {
       // changing color graph
       int a, b, value;
-
-      *viewchanged = 1;
-      set_changed();
-
       value = y_to_intensity(ypos);
-
       if(pentry <= entry) {
         a = pentry;
         b = entry;
@@ -627,64 +623,43 @@ int Colorbar_Window::handle(int event)
         a = entry;
         b = pentry;
       }
-
       // update entries from 'pentry' to 'entry'
       for(i = a; i <= b; i++) {
         int red, green, blue, alpha;
         double R, G, B, H, S, V;
-
         red = CTX.UNPACK_RED(ct->table[i]);
         green = CTX.UNPACK_GREEN(ct->table[i]);
         blue = CTX.UNPACK_BLUE(ct->table[i]);
         alpha = CTX.UNPACK_ALPHA(ct->table[i]);
-
         if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_RGB) {
-          if(p1) {
-            red = value;
-          }
-          if(p2) {
-            green = value;
-          }
-          if(p3) {
-            blue = value;
-          }
-          if(p4) {
-            alpha = value;
-          }
+          if(p1) red = value;
+          if(p2) green = value;
+          if(p3) blue = value;
+          if(p4) alpha = value;
         }
         else if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_HSV) {
           RGB_to_HSV((double)red / 255., (double)green / 255.,
                      (double)blue / 255., &H, &S, &V);
-          if(p1) {
-            H = 6. * (double)value / 255. + EPS;
-          }
-          if(p2) {
-            S = (double)value / 255.;
-          }
-          if(p3) {
-            V = (double)value / 255.;
-          }
-          if(p4) {
-            alpha = value;
-          }
+          if(p1) H = 6. * (double)value / 255. + EPS;
+          if(p2) S = (double)value / 255.;
+          if(p3) V = (double)value / 255.;
+          if(p4) alpha = value;
           HSV_to_RGB(H, S, V, &R, &G, &B);
           red = (int)(255 * R);
           green = (int)(255 * G);
           blue = (int)(255 * B);
         }
-
         ct->table[i] = CTX.PACK_COLOR(red, green, blue, alpha);
       }
-
       // redraw the color curves
       if(pentry < entry)
         redraw_range(pentry - 1, entry + 1);
       else
         redraw_range(entry - 1, pentry + 1);
-
       pentry = entry;
-
+      *viewchanged = 1;
     }
+    if(*viewchanged) do_callback();
     return 1;
   }
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 02175b1ca2..10a9d3baf4 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.537 2006-08-26 13:34:44 geuzaine Exp $
+// $Id: GUI.cpp,v 1.538 2006-08-26 17:00:25 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -382,26 +382,12 @@ static Fl_Menu_Item menu_point_display[] = {
   {0}
 };
 
-static Fl_Menu_Item menu_point_display_with_plugin[] = {
-  {"Color dot",   0, 0, 0},
-  {"3D sphere",   0, 0, 0},
-  {"Use solver plugin",   0, 0, 0},
-  {0}
-};
-
 static Fl_Menu_Item menu_line_display[] = {
   {"Color segment", 0, 0, 0},
   {"3D cylinder",   0, 0, 0},
   {0}
 };
 
-static Fl_Menu_Item menu_line_display_with_plugin[] = {
-  {"Color segment", 0, 0, 0},
-  {"3D cylinder",   0, 0, 0},
-  {"Use solver plugin",   0, 0, 0},
-  {0}
-};
-
 static Fl_Menu_Item menu_axes_mode[] = {
   {"None", 0, 0, 0},
   {"Simple axes", 0, 0, 0},
@@ -1686,8 +1672,8 @@ void GUI::create_option_window()
   // Buttons
 
   {
-    Fl_Return_Button *o = new Fl_Return_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Apply");
-    o->callback(options_ok_cb);
+    opt_redraw = new Fl_Return_Button(width - 3 * BB - 3 * WB, height - BH - WB, BB, BH, "Redraw");
+    opt_redraw->callback(redraw_cb);
   }
   {
     Fl_Button *o = new Fl_Button(width - 2 * BB - 2 * WB, height - BH - WB, BB, BH, "Save");
@@ -1727,47 +1713,56 @@ void GUI::create_option_window()
       gen_butt[10]->type(FL_TOGGLE_BUTTON);
       gen_butt[10]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[10]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[10]->callback(general_options_ok_cb);
 
       gen_butt[13] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Show tooltips");
       gen_butt[13]->type(FL_TOGGLE_BUTTON);
       gen_butt[13]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[13]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[13]->callback(general_options_ok_cb);
 
       gen_butt[6] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Show bounding boxes");
       gen_butt[6]->tooltip("(Alt+b)");
       gen_butt[6]->type(FL_TOGGLE_BUTTON);
       gen_butt[6]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[6]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[6]->callback(general_options_ok_cb);
 
       gen_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Draw simplified model during user interaction");
       gen_butt[2]->tooltip("(Alt+f)");
       gen_butt[2]->type(FL_TOGGLE_BUTTON);
       gen_butt[2]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[2]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[2]->callback(general_options_ok_cb, (void*)"fast_redraw");
 
       gen_butt[3] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Enable double buffering");
       gen_butt[3]->type(FL_TOGGLE_BUTTON);
       gen_butt[3]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[3]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[3]->callback(general_options_ok_cb);
 
       gen_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Use trackball rotation mode instead of Euler angles");
       gen_butt[5]->type(FL_TOGGLE_BUTTON);
       gen_butt[5]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[5]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[5]->callback(general_options_ok_cb);
 
       gen_butt[15] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Rotate around pseudo center of mass");
       gen_butt[15]->type(FL_TOGGLE_BUTTON);
       gen_butt[15]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[15]->selection_color(GMSH_TOGGLE_COLOR);
-      gen_butt[15]->callback(activate_cb, (void*)"rotation_center");
+      gen_butt[15]->callback(general_options_ok_cb, (void*)"rotation_center");
 
       gen_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 8 * 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 + 8 * BH, IW / 3, BH);
+      gen_value[8]->callback(general_options_ok_cb);
       gen_value[9] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 8 * BH, IW / 3, BH);
+      gen_value[9]->callback(general_options_ok_cb);
       gen_value[10] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 8 * BH, IW / 3, BH, "Rotation center");
       gen_value[10]->align(FL_ALIGN_RIGHT);
+      gen_value[10]->callback(general_options_ok_cb);
 
       o->end();
     }
@@ -1777,65 +1772,82 @@ void GUI::create_option_window()
       gen_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Axes mode");
       gen_choice[4]->menu(menu_axes_mode);
       gen_choice[4]->align(FL_ALIGN_RIGHT);
-      gen_choice[4]->callback(activate_cb, (void*)"general_axes");
       gen_choice[4]->tooltip("(Alt+a)");
+      gen_choice[4]->callback(general_options_ok_cb, (void*)"general_axes");
 
       gen_value[17] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW/3, BH);
       gen_value[17]->minimum(0.);
       gen_value[17]->step(1);
       gen_value[17]->maximum(100);
+      gen_value[17]->callback(general_options_ok_cb);
       gen_value[18] = new Fl_Value_Input(L + 2 * WB + 1*IW/3, 2 * WB + 2 * BH, IW/3, BH);
       gen_value[18]->minimum(0.);
       gen_value[18]->step(1);
       gen_value[18]->maximum(100);
+      gen_value[18]->callback(general_options_ok_cb);
       gen_value[19] = new Fl_Value_Input(L + 2 * WB + 2*IW/3, 2 * WB + 2 * BH, IW/3, BH, "Axes tics");
       gen_value[19]->minimum(0.);
       gen_value[19]->step(1);
       gen_value[19]->maximum(100);
       gen_value[19]->align(FL_ALIGN_RIGHT);
+      gen_value[19]->callback(general_options_ok_cb);
 
       gen_input[3] = new Fl_Input(L + 2 * WB, 2 * WB + 3 * BH, IW/3, BH);
+      gen_input[3]->callback(general_options_ok_cb);
       gen_input[4] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 3 * BH, IW/3, BH);
+      gen_input[4]->callback(general_options_ok_cb);
       gen_input[5] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 3 * BH, IW/3, BH, "Axes format");
       gen_input[5]->align(FL_ALIGN_RIGHT);
+      gen_input[5]->callback(general_options_ok_cb);
       
       gen_input[6] = new Fl_Input(L + 2 * WB, 2 * WB + 4 * BH, IW/3, BH);
+      gen_input[6]->callback(general_options_ok_cb);
       gen_input[7] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 4 * BH, IW/3, BH);
+      gen_input[7]->callback(general_options_ok_cb);
       gen_input[8] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 4 * BH, IW/3, BH, "Axes labels");
       gen_input[8]->align(FL_ALIGN_RIGHT);
+      gen_input[8]->callback(general_options_ok_cb);
 
       gen_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Set position and size of axes automatically");
       gen_butt[0]->type(FL_TOGGLE_BUTTON);
       gen_butt[0]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[0]->selection_color(GMSH_TOGGLE_COLOR);
-      gen_butt[0]->callback(activate_cb, (void*)"general_axes_auto");
+      gen_butt[0]->callback(general_options_ok_cb, (void*)"general_axes_auto");
       
       gen_value[20] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW / 3, BH);
+      gen_value[20]->callback(general_options_ok_cb);
       gen_value[21] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 6 * BH, IW / 3, BH);
+      gen_value[21]->callback(general_options_ok_cb);
       gen_value[22] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 6 * BH, IW / 3, BH, "Axes minimum");
       gen_value[22]->align(FL_ALIGN_RIGHT);
+      gen_value[22]->callback(general_options_ok_cb);
 
       gen_value[23] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW / 3, BH);
+      gen_value[23]->callback(general_options_ok_cb);
       gen_value[24] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 7 * BH, IW / 3, BH);
+      gen_value[24]->callback(general_options_ok_cb);
       gen_value[25] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 7 * BH, IW / 3, BH, "Axes maximum");
       gen_value[25]->align(FL_ALIGN_RIGHT);
+      gen_value[25]->callback(general_options_ok_cb);
 
       gen_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Show small axes");
       gen_butt[1]->tooltip("(Alt+Shift+a)");
       gen_butt[1]->type(FL_TOGGLE_BUTTON);
       gen_butt[1]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[1]->selection_color(GMSH_TOGGLE_COLOR);
-      gen_butt[1]->callback(activate_cb, (void*)"general_small_axes");
+      gen_butt[1]->callback(general_options_ok_cb, (void*)"general_small_axes");
 
       gen_value[26] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 2, BH);
       gen_value[26]->minimum(-1024);
       gen_value[26]->maximum(1024);
       gen_value[26]->step(1);
+      gen_value[26]->callback(general_options_ok_cb);
       gen_value[27] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 9 * BH, IW / 2, BH, "Small axes position");
       gen_value[27]->align(FL_ALIGN_RIGHT);
       gen_value[27]->minimum(-1024);
       gen_value[27]->maximum(1024);
       gen_value[27]->step(1);
+      gen_value[27]->callback(general_options_ok_cb);
 
       o->end();
     }
@@ -1845,16 +1857,19 @@ void GUI::create_option_window()
       gen_butt[7]->type(FL_TOGGLE_BUTTON);
       gen_butt[7]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[7]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[7]->callback(general_options_ok_cb);
 
       gen_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Save session information on exit");
       gen_butt[8]->type(FL_TOGGLE_BUTTON);
       gen_butt[8]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[8]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[8]->callback(general_options_ok_cb);
 
       gen_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW/2-WB, BH, "Save options on exit");
       gen_butt[9]->type(FL_TOGGLE_BUTTON);
       gen_butt[9]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[9]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[9]->callback(general_options_ok_cb);
 
       Fl_Button *b0 = new Fl_Button(L + width / 2, 2 * WB + 3 * BH, 2 * BB, BH, "Restore default options");
       b0->callback(options_restore_defaults_cb);
@@ -1863,15 +1878,18 @@ void GUI::create_option_window()
       gen_butt[14]->type(FL_TOGGLE_BUTTON);
       gen_butt[14]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[14]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[14]->callback(general_options_ok_cb);
 
       gen_value[5] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Message verbosity");
       gen_value[5]->minimum(0);
       gen_value[5]->maximum(10);
       gen_value[5]->step(1);
       gen_value[5]->align(FL_ALIGN_RIGHT);
+      gen_value[5]->callback(general_options_ok_cb);
 
       gen_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Default file name");
       gen_input[0]->align(FL_ALIGN_RIGHT);
+      gen_input[0]->callback(general_options_ok_cb);
 
       o->end();
     }
@@ -1880,9 +1898,11 @@ void GUI::create_option_window()
 
       gen_input[1] = new Fl_Input(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Text editor command");
       gen_input[1]->align(FL_ALIGN_RIGHT);
+      gen_input[1]->callback(general_options_ok_cb);
 
       gen_input[2] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Web browser command");
       gen_input[2]->align(FL_ALIGN_RIGHT);
+      gen_input[2]->callback(general_options_ok_cb);
 
       o->end();
     }
@@ -1899,48 +1919,56 @@ void GUI::create_option_window()
       gen_choice[2]->menu(menu_projection);
       gen_choice[2]->align(FL_ALIGN_RIGHT);
       gen_choice[2]->tooltip("(Alt+o)");
+      gen_choice[2]->callback(general_options_ok_cb);
 
       gen_value[14] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Z-clipping planes distance factor");
       gen_value[14]->minimum(0.1);
       gen_value[14]->maximum(10.);
       gen_value[14]->step(0.1);
       gen_value[14]->align(FL_ALIGN_RIGHT);
+      gen_value[14]->callback(general_options_ok_cb);
 
       gen_value[15] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW/2, BH);
       gen_value[15]->minimum(0.);
       gen_value[15]->maximum(10.);
       gen_value[15]->step(0.01);
       gen_value[15]->align(FL_ALIGN_RIGHT);
+      gen_value[15]->callback(general_options_ok_cb);
 
       gen_value[16] = new Fl_Value_Input(L + 2 * WB + IW/2, 2 * WB + 3 * BH, IW/2, BH, "Polygon offset factor and units");
       gen_value[16]->minimum(0.);
       gen_value[16]->maximum(10.);
       gen_value[16]->step(0.01);
       gen_value[16]->align(FL_ALIGN_RIGHT);
+      gen_value[16]->callback(general_options_ok_cb);
 
       gen_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Always apply polygon offset");
       gen_butt[4]->type(FL_TOGGLE_BUTTON);
       gen_butt[4]->down_box(GMSH_TOGGLE_BOX);
       gen_butt[4]->selection_color(GMSH_TOGGLE_COLOR);
+      gen_butt[4]->callback(general_options_ok_cb);
 
       gen_value[11] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Number of quadric subdivisions");
       gen_value[11]->minimum(3);
       gen_value[11]->maximum(30);
       gen_value[11]->step(1);
       gen_value[11]->align(FL_ALIGN_RIGHT);
+      gen_value[11]->callback(general_options_ok_cb);
 
       gen_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * 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[6]->callback(general_options_ok_cb);
 
       gen_value[7] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Line width");
       gen_value[7]->minimum(0.1);
       gen_value[7]->maximum(50);
       gen_value[7]->step(0.1);
       gen_value[7]->align(FL_ALIGN_RIGHT);
-
+      gen_value[7]->callback(general_options_ok_cb);
+      
       static Fl_Menu_Item menu_genvectype[] = {
 	{"Line", 0, 0, 0},
 	{"Arrow", 0, 0, 0},
@@ -1951,6 +1979,7 @@ void GUI::create_option_window()
       gen_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Vector display");
       gen_choice[0]->menu(menu_genvectype);
       gen_choice[0]->align(FL_ALIGN_RIGHT);
+      gen_choice[0]->callback(general_options_ok_cb);
 
       Fl_Button *b = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 8 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
       b->callback(general_arrow_param_cb);
@@ -1958,12 +1987,14 @@ void GUI::create_option_window()
       gen_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Font");
       gen_choice[1]->menu(menu_font_names);
       gen_choice[1]->align(FL_ALIGN_RIGHT);
+      gen_choice[1]->callback(general_options_ok_cb);
 
       gen_value[12] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Font size");
       gen_value[12]->minimum(5);
       gen_value[12]->maximum(40);
       gen_value[12]->step(1);
       gen_value[12]->align(FL_ALIGN_RIGHT);
+      gen_value[12]->callback(general_options_ok_cb);
 
       o->end();
     }
@@ -1975,44 +2006,44 @@ void GUI::create_option_window()
       gen_value[2]->minimum(-1.);
       gen_value[2]->maximum(1.);
       gen_value[2]->step(0.01);
-      gen_value[2]->callback(general_options_light_cb, (void*)"x");
+      gen_value[2]->callback(general_options_ok_cb, (void*)"light_value");
 
       gen_value[3] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 1 * BH, IW/3, BH);
       gen_value[3]->minimum(-1.);
       gen_value[3]->maximum(1.);
       gen_value[3]->step(0.01);
-      gen_value[3]->callback(general_options_light_cb, (void*)"y");
+      gen_value[3]->callback(general_options_ok_cb, (void*)"light_value");
 
       gen_value[4] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 1 * BH, IW/3, BH, "Light position");
       gen_value[4]->minimum(-1.);
       gen_value[4]->maximum(1.);
       gen_value[4]->step(0.01);
       gen_value[4]->align(FL_ALIGN_RIGHT);
-      gen_value[4]->callback(general_options_light_cb, (void*)"z");
+      gen_value[4]->callback(general_options_ok_cb, (void*)"light_value");
 
       gen_value[13] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Light position divisor");
       gen_value[13]->minimum(0.);
       gen_value[13]->maximum(1.);
       gen_value[13]->step(0.01);
       gen_value[13]->align(FL_ALIGN_RIGHT);
-      gen_value[13]->callback(general_options_light_cb, (void*)"w");
+      gen_value[13]->callback(general_options_ok_cb);
 
       gen_sphere = new SpherePosition_Widget(L + 2 * WB + 2 * IW, 2 * WB + 1 * BH, 2 * BH);
-      gen_sphere->callback(general_options_light_cb, (void*)"xyz");
+      gen_sphere->callback(general_options_ok_cb, (void*)"light_sphere");
 
       gen_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Material shininess");
       gen_value[1]->minimum(0);
       gen_value[1]->maximum(10);
       gen_value[1]->step(0.1);
       gen_value[1]->align(FL_ALIGN_RIGHT);
-      gen_value[1]->callback(general_options_light_cb, (void*)"shine");
+      gen_value[1]->callback(general_options_ok_cb);
 
       gen_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Material shininess exponent");
       gen_value[0]->minimum(0);
       gen_value[0]->maximum(128);
       gen_value[0]->step(1);
       gen_value[0]->align(FL_ALIGN_RIGHT);
-      gen_value[0]->callback(general_options_light_cb, (void*)"shine_exponent");
+      gen_value[0]->callback(general_options_ok_cb);
 
       o->end();
     }
@@ -2029,9 +2060,9 @@ void GUI::create_option_window()
 
       gen_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Predefined color scheme");
       gen_choice[3]->menu(menu_color_scheme);
-      gen_choice[3]->callback(general_options_color_scheme_cb);
       gen_choice[3]->align(FL_ALIGN_RIGHT);
       gen_choice[3]->tooltip("(Alt+c)");
+      gen_choice[3]->callback(general_options_color_scheme_cb);
 
       static Fl_Menu_Item menu_bg_grad[] = {
 	{"None", 0, 0, 0},
@@ -2044,6 +2075,7 @@ void GUI::create_option_window()
       gen_choice[5] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Background gradient");
       gen_choice[5]->menu(menu_bg_grad);
       gen_choice[5]->align(FL_ALIGN_RIGHT);
+      gen_choice[5]->callback(general_options_ok_cb);
 
       Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 3 * WB + 3 * BH, IW + 20, height - 5 * WB - 3 * BH);
       int i = 0;
@@ -2073,6 +2105,7 @@ void GUI::create_option_window()
       geo_butt[8]->type(FL_TOGGLE_BUTTON);
       geo_butt[8]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[8]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[8]->callback(geometry_options_ok_cb);
 
       o->end();
     }
@@ -2084,56 +2117,66 @@ void GUI::create_option_window()
       geo_butt[0]->type(FL_TOGGLE_BUTTON);
       geo_butt[0]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[0]->selection_color(GMSH_TOGGLE_COLOR);
-
+      geo_butt[0]->callback(geometry_options_ok_cb);
+      
       geo_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Lines");
       geo_butt[1]->tooltip("(Alt+l)");
       geo_butt[1]->type(FL_TOGGLE_BUTTON);
       geo_butt[1]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[1]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[1]->callback(geometry_options_ok_cb);
 
       geo_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surfaces");
       geo_butt[2]->tooltip("(Alt+s)");
       geo_butt[2]->type(FL_TOGGLE_BUTTON);
       geo_butt[2]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[2]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[2]->callback(geometry_options_ok_cb);
 
       geo_butt[3] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Volumes");
       geo_butt[3]->tooltip("(Alt+v)");
       geo_butt[3]->type(FL_TOGGLE_BUTTON);
       geo_butt[3]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[3]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[3]->callback(geometry_options_ok_cb);
 
       geo_butt[4] = new Fl_Check_Button(L + width / 2, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Point numbers");
       geo_butt[4]->type(FL_TOGGLE_BUTTON);
       geo_butt[4]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[4]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[4]->callback(geometry_options_ok_cb);
 
       geo_butt[5] = new Fl_Check_Button(L + width / 2, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Line numbers");
       geo_butt[5]->type(FL_TOGGLE_BUTTON);
       geo_butt[5]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[5]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[5]->callback(geometry_options_ok_cb);
 
       geo_butt[6] = new Fl_Check_Button(L + width / 2, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surface numbers");
       geo_butt[6]->type(FL_TOGGLE_BUTTON);
       geo_butt[6]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[6]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[6]->callback(geometry_options_ok_cb);
 
       geo_butt[7] = new Fl_Check_Button(L + width / 2, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Volume numbers");
       geo_butt[7]->type(FL_TOGGLE_BUTTON);
       geo_butt[7]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[7]->selection_color(GMSH_TOGGLE_COLOR);
+      geo_butt[7]->callback(geometry_options_ok_cb);
 
       geo_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Normals");
       geo_value[0]->minimum(0);
       geo_value[0]->maximum(500);
       geo_value[0]->step(1);
       geo_value[0]->align(FL_ALIGN_RIGHT);
+      geo_value[0]->callback(geometry_options_ok_cb);
 
       geo_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Tangents");
       geo_value[1]->minimum(0);
       geo_value[1]->maximum(500);
       geo_value[1]->step(1);
       geo_value[1]->align(FL_ALIGN_RIGHT);
+      geo_value[1]->callback(geometry_options_ok_cb);
 
       o->end();
     }
@@ -2142,43 +2185,42 @@ void GUI::create_option_window()
       o->hide();
 
       geo_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Point display");
-      GMSH_Solve_Plugin *sp = GMSH_PluginManager::instance()->findSolverPlugin();   
-      if(sp)
-	geo_choice[0]->menu(menu_point_display_with_plugin);
-      else
-	geo_choice[0]->menu(menu_point_display);
+      geo_choice[0]->menu(menu_point_display);
       geo_choice[0]->align(FL_ALIGN_RIGHT);
+      geo_choice[0]->callback(geometry_options_ok_cb);
 
       geo_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Point size");
       geo_value[3]->minimum(0.1);
       geo_value[3]->maximum(50);
       geo_value[3]->step(0.1);
       geo_value[3]->align(FL_ALIGN_RIGHT);
+      geo_value[3]->callback(geometry_options_ok_cb);
 
       geo_value[5] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Selected point size");
       geo_value[5]->minimum(0.1);
       geo_value[5]->maximum(50);
       geo_value[5]->step(0.1);
       geo_value[5]->align(FL_ALIGN_RIGHT);
+      geo_value[5]->callback(geometry_options_ok_cb);
 
       geo_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Line display");
-      if(sp)
-	geo_choice[1]->menu(menu_line_display_with_plugin);
-      else
-	geo_choice[1]->menu(menu_line_display);
+      geo_choice[1]->menu(menu_line_display);
       geo_choice[1]->align(FL_ALIGN_RIGHT);	
+      geo_choice[1]->callback(geometry_options_ok_cb);
 
       geo_value[4] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
       geo_value[4]->minimum(0.1);
       geo_value[4]->maximum(50);
       geo_value[4]->step(0.1);
       geo_value[4]->align(FL_ALIGN_RIGHT);
+      geo_value[4]->callback(geometry_options_ok_cb);
 
       geo_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Selected line width");
       geo_value[6]->minimum(0.1);
       geo_value[6]->maximum(50);
       geo_value[6]->step(0.1);
       geo_value[6]->align(FL_ALIGN_RIGHT);
+      geo_value[6]->callback(geometry_options_ok_cb);
 
       o->end();
     }
@@ -2191,6 +2233,7 @@ void GUI::create_option_window()
       geo_butt[9]->down_box(GMSH_TOGGLE_BOX);
       geo_butt[9]->selection_color(GMSH_TOGGLE_COLOR);
       geo_butt[9]->tooltip("(Alt+w)");
+      geo_butt[9]->callback(geometry_options_ok_cb);
 
       o->end();
     }
@@ -2244,38 +2287,45 @@ void GUI::create_option_window()
       mesh_choice[2] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "2D algorithm");
       mesh_choice[2]->menu(menu_2d_algo);
       mesh_choice[2]->align(FL_ALIGN_RIGHT);
+      mesh_choice[2]->callback(mesh_options_ok_cb);
 
       mesh_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "3D algorithm");
       mesh_choice[3]->menu(menu_3d_algo);
       mesh_choice[3]->align(FL_ALIGN_RIGHT);
+      mesh_choice[3]->callback(mesh_options_ok_cb);
 
       mesh_choice[5] = new Fl_Choice(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Recombine algorithm");
       mesh_choice[5]->menu(menu_recombine_algo);
       mesh_choice[5]->align(FL_ALIGN_RIGHT);
+      mesh_choice[5]->callback(mesh_options_ok_cb);
 
       mesh_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Number of smoothing steps");
       mesh_value[0]->minimum(0);
       mesh_value[0]->maximum(100);
       mesh_value[0]->step(1);
       mesh_value[0]->align(FL_ALIGN_RIGHT);
+      mesh_value[0]->callback(mesh_options_ok_cb);
 
       mesh_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Mesh scaling factor");
       mesh_value[1]->minimum(0.001);
       mesh_value[1]->maximum(1000);
       mesh_value[1]->step(0.001);
       mesh_value[1]->align(FL_ALIGN_RIGHT);
+      mesh_value[1]->callback(mesh_options_ok_cb);
 
       mesh_value[2] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Characteristic length factor");
       mesh_value[2]->minimum(0.001);
       mesh_value[2]->maximum(1000);
       mesh_value[2]->step(0.001);
       mesh_value[2]->align(FL_ALIGN_RIGHT);
+      mesh_value[2]->callback(mesh_options_ok_cb);
 
       mesh_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Random perturbation factor");
       mesh_value[3]->minimum(1.e-6);
       mesh_value[3]->maximum(1.e-1);
       mesh_value[3]->step(1.e-6);
       mesh_value[3]->align(FL_ALIGN_RIGHT);
+      mesh_value[3]->callback(mesh_options_ok_cb);
 
       mesh_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Optimize quality of tetrahedral elements");
       mesh_butt[2]->type(FL_TOGGLE_BUTTON);
@@ -2284,16 +2334,19 @@ void GUI::create_option_window()
 #if !defined(HAVE_NETGEN)
       mesh_butt[2]->deactivate();
 #endif
+      mesh_butt[2]->callback(mesh_options_ok_cb);
 
       mesh_butt[3] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 9 * BH, BW, BH, "Generate second order elements");
       mesh_butt[3]->type(FL_TOGGLE_BUTTON);
       mesh_butt[3]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[3]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[3]->callback(mesh_options_ok_cb);
 
       mesh_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 10 * BH, BW, BH, "Constrain background mesh with characteristic length field");
       mesh_butt[5]->type(FL_TOGGLE_BUTTON);
       mesh_butt[5]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[5]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[5]->callback(mesh_options_ok_cb);
 
       o->end();
     }
@@ -2307,47 +2360,49 @@ void GUI::create_option_window()
       mesh_value[19]->maximum(1.e-3);
       mesh_value[19]->step(1.e-7);
       mesh_value[19]->align(FL_ALIGN_RIGHT);
+      mesh_value[19]->callback(mesh_options_ok_cb);
 
       mesh_value[20] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Dihedral angle threshold");
       mesh_value[20]->minimum(0);
       mesh_value[20]->maximum(90);
       mesh_value[20]->step(1);
       mesh_value[20]->align(FL_ALIGN_RIGHT);
+      mesh_value[20]->callback(mesh_options_ok_cb);
 
       mesh_value[21] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Edge prolongation threshold");
       mesh_value[21]->minimum(0);
       mesh_value[21]->maximum(100);
       mesh_value[21]->step(1);
       mesh_value[21]->align(FL_ALIGN_RIGHT); 
+      mesh_value[21]->callback(mesh_options_ok_cb);
 
       mesh_value[22] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Elements per radius of curvature");
       mesh_value[22]->minimum(1);
       mesh_value[22]->maximum(10);
       mesh_value[22]->step(.1);
       mesh_value[22]->align(FL_ALIGN_RIGHT); 
+      mesh_value[22]->callback(mesh_options_ok_cb);
 
       mesh_value[23] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "LC / minimum element size");
       mesh_value[23]->minimum(10);
       mesh_value[23]->maximum(10000);
       mesh_value[23]->step(10);
       mesh_value[23]->align(FL_ALIGN_RIGHT); 
+      mesh_value[23]->callback(mesh_options_ok_cb);
 
       mesh_value[24] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "LC / target element size");
       mesh_value[24]->minimum(1);
       mesh_value[24]->maximum(1000);
       mesh_value[24]->step(1);
       mesh_value[24]->align(FL_ALIGN_RIGHT); 
+      mesh_value[24]->callback(mesh_options_ok_cb);
 
       mesh_value[25] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Beta smoothing factor");
       mesh_value[25]->minimum(0);
       mesh_value[25]->maximum(1);
       mesh_value[25]->step(.01);
       mesh_value[25]->align(FL_ALIGN_RIGHT); 
-
-      //mesh_butt[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Allow coarsening of the initial mesh");
-      //mesh_butt[1]->type(FL_TOGGLE_BUTTON);
-      //mesh_butt[1]->down_box(GMSH_TOGGLE_BOX);
-      //mesh_butt[1]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_value[25]->callback(mesh_options_ok_cb);
 
       o->end();
     }
@@ -2360,55 +2415,65 @@ void GUI::create_option_window()
       mesh_butt[6]->type(FL_TOGGLE_BUTTON);
       mesh_butt[6]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[6]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[6]->callback(mesh_options_ok_cb);
 
       mesh_butt[7] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Lines");
       mesh_butt[7]->tooltip("(Alt+Shift+l)");
       mesh_butt[7]->type(FL_TOGGLE_BUTTON);
       mesh_butt[7]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[7]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[7]->callback(mesh_options_ok_cb);
 
       mesh_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surface edges");
       mesh_butt[8]->tooltip("(Alt+Shift+s)");
       mesh_butt[8]->type(FL_TOGGLE_BUTTON);
       mesh_butt[8]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[8]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[8]->callback(mesh_options_ok_cb);
 
       mesh_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Surface faces");
       mesh_butt[9]->tooltip("(Alt+Shift+d)");
       mesh_butt[9]->type(FL_TOGGLE_BUTTON);
       mesh_butt[9]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[9]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[9]->callback(mesh_options_ok_cb);
 
       mesh_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW / 2 - WB, BH, "Volume edges");
       mesh_butt[10]->tooltip("(Alt+Shift+v)");
       mesh_butt[10]->type(FL_TOGGLE_BUTTON);
       mesh_butt[10]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[10]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[10]->callback(mesh_options_ok_cb);
 
       mesh_butt[11] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW / 2 - WB, BH, "Volume faces");
       mesh_butt[11]->type(FL_TOGGLE_BUTTON);
       mesh_butt[11]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[11]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[11]->callback(mesh_options_ok_cb);
 
       mesh_butt[12] = new Fl_Check_Button(L + width / 2, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Node labels");
       mesh_butt[12]->type(FL_TOGGLE_BUTTON);
       mesh_butt[12]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[12]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[12]->callback(mesh_options_ok_cb);
 
       mesh_butt[13] = new Fl_Check_Button(L + width / 2, 2 * WB + 2 * BH, BW / 2 - WB, BH, "Line labels");
       mesh_butt[13]->type(FL_TOGGLE_BUTTON);
       mesh_butt[13]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[13]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[13]->callback(mesh_options_ok_cb);
 
       mesh_butt[14] = new Fl_Check_Button(L + width / 2, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Surface labels");
       mesh_butt[14]->type(FL_TOGGLE_BUTTON);
       mesh_butt[14]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[14]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[14]->callback(mesh_options_ok_cb);
 
       mesh_butt[15] = new Fl_Check_Button(L + width / 2, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Volume labels");
       mesh_butt[15]->type(FL_TOGGLE_BUTTON);
       mesh_butt[15]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[15]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[15]->callback(mesh_options_ok_cb);
 
       static Fl_Menu_Item menu_label_type[] = {
         {"Number", 0, 0, 0},
@@ -2421,12 +2486,14 @@ void GUI::create_option_window()
       mesh_choice[7] = new Fl_Choice(L + width / 2, 2 * WB + 5 * BH, width/4 - 2*WB, BH, "Label type");
       mesh_choice[7]->menu(menu_label_type);
       mesh_choice[7]->align(FL_ALIGN_RIGHT);
+      mesh_choice[7]->callback(mesh_options_ok_cb);
 
       mesh_value[12] = new Fl_Value_Input(L + width / 2, 2 * WB + 6 * BH, width/4 - 2*WB, BH, "Label frequency");
-      mesh_value[12]->minimum(0.0);
-      mesh_value[12]->maximum(100.0);
-      mesh_value[12]->step(0.1);
+      mesh_value[12]->minimum(0);
+      mesh_value[12]->maximum(100);
+      mesh_value[12]->step(1);
       mesh_value[12]->align(FL_ALIGN_RIGHT);
+      mesh_value[12]->callback(mesh_options_ok_cb);
 
       static Fl_Menu_Item menu_mesh_element_types[] = {
 	{"Triangles",   0, 0, 0, FL_MENU_TOGGLE},
@@ -2440,18 +2507,21 @@ void GUI::create_option_window()
 
       mesh_menu_butt = new Fl_Menu_Button(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Elements");
       mesh_menu_butt->menu(menu_mesh_element_types);
+      mesh_menu_butt->callback(mesh_options_ok_cb);
 
       mesh_value[4] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW / 4, BH);
       mesh_value[4]->minimum(0);
       mesh_value[4]->maximum(1);
       mesh_value[4]->step(0.01);
       mesh_value[4]->align(FL_ALIGN_RIGHT);
+      mesh_value[4]->callback(mesh_options_ok_cb);
 
       mesh_value[5] = new Fl_Value_Input(L + 2 * WB + IW / 4, 2 * WB + 8 * BH, IW / 2 - IW / 4, BH);
       mesh_value[5]->minimum(0);
       mesh_value[5]->maximum(1);
       mesh_value[5]->step(0.01);
       mesh_value[5]->align(FL_ALIGN_RIGHT);
+      mesh_value[5]->callback(mesh_options_ok_cb);
 
       static Fl_Menu_Item menu_quality_type[] = {
         {"Gamma", 0, 0, 0},
@@ -2462,24 +2532,29 @@ void GUI::create_option_window()
       mesh_choice[6] = new Fl_Choice(L + 2 * WB + IW / 2, 2 * WB + 8 * BH, IW/2, BH, "Quality range");
       mesh_choice[6]->menu(menu_quality_type);
       mesh_choice[6]->align(FL_ALIGN_RIGHT);
+      mesh_choice[6]->callback(mesh_options_ok_cb);
 
       mesh_value[6] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 2, BH);
       mesh_value[6]->align(FL_ALIGN_RIGHT);
+      mesh_value[6]->callback(mesh_options_ok_cb);
 
       mesh_value[7] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 9 * BH, IW / 2, BH, "Size range");
       mesh_value[7]->align(FL_ALIGN_RIGHT);
+      mesh_value[7]->callback(mesh_options_ok_cb);
 
       mesh_value[8] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Normals");
       mesh_value[8]->minimum(0);
       mesh_value[8]->maximum(500);
       mesh_value[8]->step(1);
       mesh_value[8]->align(FL_ALIGN_RIGHT);
+      mesh_value[8]->callback(mesh_options_ok_cb);
 
       mesh_value[13] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Tangents");
       mesh_value[13]->minimum(0);
       mesh_value[13]->maximum(200);
       mesh_value[13]->step(1.0);
       mesh_value[13]->align(FL_ALIGN_RIGHT);
+      mesh_value[13]->callback(mesh_options_ok_cb);
 
       o->end();
     }
@@ -2491,52 +2566,54 @@ void GUI::create_option_window()
       mesh_butt[16]->type(FL_TOGGLE_BUTTON);
       mesh_butt[16]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[16]->selection_color(GMSH_TOGGLE_COLOR);
-      mesh_butt[16]->callback(activate_cb, (void*)"mesh_cut_plane");
+      mesh_butt[16]->callback(mesh_options_ok_cb, (void*)"mesh_cut_plane");
 
       mesh_cut_plane = new Fl_Group(L + 2 * WB, 2 * WB + 2 * BH, width - 2 * WB, 6 * BH, 0);
 
       int ii = fontsize;
       Fl_Button *invert = new Fl_Button(L + 2 * WB, 2 * WB + 2 * BH, ii, 4*BH, "-");
-      invert->callback(mesh_cut_plane_invert_cb);
       invert->tooltip("Invert orientation");
+      invert->callback(mesh_options_ok_cb, (void*)"cut_plane_invert");
 
       mesh_value[14] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 2 * BH, IW - ii, BH, "A");
       mesh_value[14]->align(FL_ALIGN_RIGHT);
-      mesh_value[14]->callback(mesh_cut_plane_cb);
       mesh_value[14]->step(0.01);
       mesh_value[14]->minimum(-1.0);
       mesh_value[14]->maximum(1.0);
+      mesh_value[14]->callback(mesh_options_ok_cb);
 
       mesh_value[15] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 3 * BH, IW - ii, BH, "B");
       mesh_value[15]->align(FL_ALIGN_RIGHT);
-      mesh_value[15]->callback(mesh_cut_plane_cb);
       mesh_value[15]->step(0.01);
       mesh_value[15]->minimum(-1.0);
       mesh_value[15]->maximum(1.0);
+      mesh_value[15]->callback(mesh_options_ok_cb);
 
       mesh_value[16] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 4 * BH, IW - ii, BH, "C");
       mesh_value[16]->align(FL_ALIGN_RIGHT);
-      mesh_value[16]->callback(mesh_cut_plane_cb);
       mesh_value[16]->step(0.01);
       mesh_value[16]->minimum(-1.0);
       mesh_value[16]->maximum(1.0);
+      mesh_value[16]->callback(mesh_options_ok_cb);
 
       mesh_value[17] = new Fl_Value_Input(L + 2 * WB + ii, 2 * WB + 5 * BH, IW - ii, BH, "D");
       mesh_value[17]->align(FL_ALIGN_RIGHT);
-      mesh_value[17]->callback(mesh_cut_plane_cb);
       mesh_value[17]->step(0.01);
       mesh_value[17]->minimum(-1.0);
       mesh_value[17]->maximum(1.0);
+      mesh_value[17]->callback(mesh_options_ok_cb);
 
       mesh_butt[22] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW, BH, "Draw only intersecting volume layer");
       mesh_butt[22]->type(FL_TOGGLE_BUTTON);
       mesh_butt[22]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[22]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[22]->callback(mesh_options_ok_cb);
 
       mesh_butt[23] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 7 * BH, BW, BH, "Cut only volume elements");
       mesh_butt[23]->type(FL_TOGGLE_BUTTON);
       mesh_butt[23]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[23]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[23]->callback(mesh_options_ok_cb);
 
       mesh_cut_plane->end();
 
@@ -2551,27 +2628,32 @@ void GUI::create_option_window()
       mesh_value[9]->maximum(1);
       mesh_value[9]->step(0.01);
       mesh_value[9]->align(FL_ALIGN_RIGHT);
+      mesh_value[9]->callback(mesh_options_ok_cb);
 
       mesh_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Point display");
       mesh_choice[0]->menu(menu_point_display);
       mesh_choice[0]->align(FL_ALIGN_RIGHT);
+      mesh_choice[0]->callback(mesh_options_ok_cb);
 
       mesh_value[10] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Point size");
       mesh_value[10]->minimum(0.1);
       mesh_value[10]->maximum(50);
       mesh_value[10]->step(0.1);
       mesh_value[10]->align(FL_ALIGN_RIGHT);
+      mesh_value[10]->callback(mesh_options_ok_cb);
 
       mesh_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Line display");
       mesh_choice[1]->menu(menu_line_display);
       mesh_choice[1]->align(FL_ALIGN_RIGHT);
       mesh_choice[1]->deactivate(); // don't give false hopes, as it's not used anywhere right now
+      mesh_choice[1]->callback(mesh_options_ok_cb);
 
       mesh_value[11] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
       mesh_value[11]->minimum(0.1);
       mesh_value[11]->maximum(50);
       mesh_value[11]->step(0.1);
       mesh_value[11]->align(FL_ALIGN_RIGHT);
+      mesh_value[11]->callback(mesh_options_ok_cb);
 
       o->end();
     }
@@ -2584,34 +2666,39 @@ void GUI::create_option_window()
       mesh_butt[17]->type(FL_TOGGLE_BUTTON);
       mesh_butt[17]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[17]->selection_color(GMSH_TOGGLE_COLOR);
-      mesh_butt[17]->callback(activate_cb, (void*)"mesh_light");
+      mesh_butt[17]->callback(mesh_options_ok_cb, (void*)"mesh_light");
 
       mesh_butt[20] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Enable lighting of lines");
       mesh_butt[20]->type(FL_TOGGLE_BUTTON);
       mesh_butt[20]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[20]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[20]->callback(mesh_options_ok_cb);
 
       mesh_butt[18] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Use two-side lighting");
       mesh_butt[18]->type(FL_TOGGLE_BUTTON);
       mesh_butt[18]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[18]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[18]->callback(mesh_options_ok_cb);
 
       mesh_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Reverse all normals");
       mesh_butt[0]->tooltip("(Alt+Shift+w)");
       mesh_butt[0]->type(FL_TOGGLE_BUTTON);
       mesh_butt[0]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[0]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[0]->callback(mesh_options_ok_cb);
 
       mesh_butt[19] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Smooth normals");
       mesh_butt[19]->type(FL_TOGGLE_BUTTON);
       mesh_butt[19]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[19]->selection_color(GMSH_TOGGLE_COLOR);
+      mesh_butt[19]->callback(mesh_options_ok_cb);
 
       mesh_value[18] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Smoothing threshold angle");
       mesh_value[18]->minimum(0.);
       mesh_value[18]->maximum(180.);
       mesh_value[18]->step(1.);
       mesh_value[18]->align(FL_ALIGN_RIGHT);
+      mesh_value[18]->callback(mesh_options_ok_cb);
 
       o->end();
     }
@@ -2629,6 +2716,7 @@ void GUI::create_option_window()
       mesh_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Coloring mode");
       mesh_choice[4]->menu(menu_mesh_color);
       mesh_choice[4]->align(FL_ALIGN_RIGHT);
+      mesh_choice[4]->callback(mesh_options_ok_cb);
 
       Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 3 * WB + 2 * BH, IW + 20, height - 5 * WB - 2 * BH);
       int i = 0;
@@ -2660,14 +2748,17 @@ void GUI::create_option_window()
 	solver_value[0]->maximum(10);
 	solver_value[0]->step(1);
 	solver_value[0]->align(FL_ALIGN_RIGHT);
+	solver_value[0]->callback(solver_options_ok_cb);
 
 	solver_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Socket name");
 	solver_input[0]->align(FL_ALIGN_RIGHT);
+	solver_input[0]->callback(solver_options_ok_cb);
 
 	solver_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Always listen to incoming connection requests");
 	solver_butt[0]->type(FL_TOGGLE_BUTTON);
 	solver_butt[0]->down_box(GMSH_TOGGLE_BOX);
 	solver_butt[0]->selection_color(GMSH_TOGGLE_COLOR);
+	solver_butt[0]->callback(solver_options_ok_cb);
 	
 	o->end();
       }
@@ -2697,27 +2788,32 @@ void GUI::create_option_window()
       post_choice[0] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "View links");
       post_choice[0]->menu(menu_links);
       post_choice[0]->align(FL_ALIGN_RIGHT);
+      post_choice[0]->callback(post_options_ok_cb);
 
       post_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Animation delay");
       post_value[0]->minimum(0);
       post_value[0]->maximum(10);
       post_value[0]->step(0.01);
       post_value[0]->align(FL_ALIGN_RIGHT);
+      post_value[0]->callback(post_options_ok_cb);
 
       post_butt[0] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Cycle through views instead of time steps");
       post_butt[0]->type(FL_TOGGLE_BUTTON);
       post_butt[0]->down_box(GMSH_TOGGLE_BOX);
       post_butt[0]->selection_color(GMSH_TOGGLE_COLOR);
+      post_butt[0]->callback(post_options_ok_cb);
 
       post_butt[1] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Remove original views after combination");
       post_butt[1]->type(FL_TOGGLE_BUTTON);
       post_butt[1]->down_box(GMSH_TOGGLE_BOX);
       post_butt[1]->selection_color(GMSH_TOGGLE_COLOR);
+      post_butt[1]->callback(post_options_ok_cb);
 
       post_butt[2] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Draw value scales horizontally");
       post_butt[2]->type(FL_TOGGLE_BUTTON);
       post_butt[2]->down_box(GMSH_TOGGLE_BOX);
       post_butt[2]->selection_color(GMSH_TOGGLE_COLOR);
+      post_butt[2]->callback(post_options_ok_cb);
 
       o->end();
     }
@@ -2744,9 +2840,11 @@ void GUI::create_option_window()
       view_choice[13] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Plot type");
       view_choice[13]->menu(menu_plot_type);
       view_choice[13]->align(FL_ALIGN_RIGHT);
+      view_choice[13]->callback(view_options_ok_cb);
 
       view_input[0] = new Fl_Input(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "View name");
       view_input[0]->align(FL_ALIGN_RIGHT);
+      view_input[0]->callback(view_options_ok_cb);
 
       int sw = (int)(1.5 * fontsize);
       view_butt_rep[0] = new Fl_Repeat_Button(L + 2 * WB, 2 * WB + 3 * BH, sw, BH, "-");
@@ -2770,6 +2868,7 @@ void GUI::create_option_window()
       view_value[30]->minimum(1);
       view_value[30]->maximum(256);
       view_value[30]->step(1);
+      view_value[30]->callback(view_options_ok_cb);
 
       static Fl_Menu_Item menu_iso[] = {
         {"Iso-values", 0, 0, 0},
@@ -2782,6 +2881,7 @@ void GUI::create_option_window()
       view_choice[0]->menu(menu_iso);
       view_choice[0]->align(FL_ALIGN_RIGHT);
       view_choice[0]->tooltip("(Alt+t)");
+      view_choice[0]->callback(view_options_ok_cb);
 
       static Fl_Menu_Item menu_range[] = {
         {"Default", 0, 0, 0},
@@ -2792,23 +2892,26 @@ void GUI::create_option_window()
       view_choice[7] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Range mode");
       view_choice[7]->menu(menu_range);
       view_choice[7]->align(FL_ALIGN_RIGHT);
-      view_choice[7]->callback(activate_cb, (void*)"custom_range");
+      view_choice[7]->callback(view_options_ok_cb, (void*)"custom_range");
 
       int sw2 = (int)(2.5 * fontsize);
       view_push_butt[1] = new Fl_Button(L + 2 * WB, 2 * WB + 7 * BH, sw2, BH, "Min");
-      view_push_butt[1]->callback(view_options_custom_set_cb, (void*)"Min");
+      view_push_butt[1]->callback(view_options_ok_cb, (void*)"range_min");
       view_value[31] = new Fl_Value_Input(L + 2 * WB + sw2, 2 * WB + 7 * BH, IW - sw2, BH, "Custom minimum");
       view_value[31]->align(FL_ALIGN_RIGHT);
+      view_value[31]->callback(view_options_ok_cb);
 
       view_push_butt[2] = new Fl_Button(L + 2 * WB, 2 * WB + 8 * BH, sw2, BH, "Max");
-      view_push_butt[2]->callback(view_options_custom_set_cb, (void*)"Max");
+      view_push_butt[2]->callback(view_options_ok_cb, (void*)"range_max");
       view_value[32] = new Fl_Value_Input(L + 2 * WB + sw2, 2 * WB + 8 * BH, IW - sw2, BH, "Custom maximum");
       view_value[32]->align(FL_ALIGN_RIGHT);
+      view_value[32]->callback(view_options_ok_cb);
 
       view_butt[38] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 9 * BH, BW, BH, "Saturate out-of-range values");
       view_butt[38]->type(FL_TOGGLE_BUTTON);
       view_butt[38]->down_box(GMSH_TOGGLE_BOX);
       view_butt[38]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[38]->callback(view_options_ok_cb);
 
       static Fl_Menu_Item menu_scale[] = {
         {"Linear", 0, 0, 0},
@@ -2819,9 +2922,11 @@ void GUI::create_option_window()
       view_choice[1] = new Fl_Choice(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Value scale mode");
       view_choice[1]->menu(menu_scale);
       view_choice[1]->align(FL_ALIGN_RIGHT);
+      view_choice[1]->callback(view_options_ok_cb);
 
       view_input[1] = new Fl_Input(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Number display format");
       view_input[1]->align(FL_ALIGN_RIGHT);
+      view_input[1]->callback(view_options_ok_cb);
 
       view_range->end();
 
@@ -2834,74 +2939,93 @@ void GUI::create_option_window()
       view_choice[8] = new Fl_Choice(L + 2 * WB, 2 * WB + 1 * BH, IW, BH, "Axes mode");
       view_choice[8]->menu(menu_axes_mode);
       view_choice[8]->align(FL_ALIGN_RIGHT);
-      view_choice[8]->callback(activate_cb, (void*)"view_axes");
       view_choice[8]->tooltip("(Alt+g)");
+      view_choice[8]->callback(view_options_ok_cb, (void*)"view_axes");
 
       view_value[3] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 2 * BH, IW/3, BH);
       view_value[3]->minimum(0.);
       view_value[3]->step(1);
       view_value[3]->maximum(100);
+      view_value[3]->callback(view_options_ok_cb);
       view_value[4] = new Fl_Value_Input(L + 2 * WB + 1*IW/3, 2 * WB + 2 * BH, IW/3, BH);
       view_value[4]->minimum(0.);
       view_value[4]->step(1);
       view_value[4]->maximum(100);
+      view_value[4]->callback(view_options_ok_cb);
       view_value[5] = new Fl_Value_Input(L + 2 * WB + 2*IW/3, 2 * WB + 2 * BH, IW/3, BH, "Axes tics");
       view_value[5]->minimum(0.);
       view_value[5]->step(1);
       view_value[5]->maximum(100);
       view_value[5]->align(FL_ALIGN_RIGHT);
+      view_value[5]->callback(view_options_ok_cb);
 
       view_input[7] = new Fl_Input(L + 2 * WB, 2 * WB + 3 * BH, IW/3, BH);
+      view_input[7]->callback(view_options_ok_cb);
       view_input[8] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 3 * BH, IW/3, BH);
+      view_input[8]->callback(view_options_ok_cb);
       view_input[9] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 3 * BH, IW/3, BH, "Axes format");
       view_input[9]->align(FL_ALIGN_RIGHT);
+      view_input[9]->callback(view_options_ok_cb);
       
       view_input[10] = new Fl_Input(L + 2 * WB, 2 * WB + 4 * BH, IW/3, BH);
+      view_input[10]->callback(view_options_ok_cb);
       view_input[11] = new Fl_Input(L + 2 * WB + 1*IW/3, 2 * WB + 4 * BH, IW/3, BH);
+      view_input[11]->callback(view_options_ok_cb);
       view_input[12] = new Fl_Input(L + 2 * WB + 2*IW/3, 2 * WB + 4 * BH, IW/3, BH, "Axes labels");
       view_input[12]->align(FL_ALIGN_RIGHT);
+      view_input[12]->callback(view_options_ok_cb);
       
-      view_butt[25] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW / 2 - WB, BH, "Set position and size of 3D axes automatically");
+      view_butt[25] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Set position and size of 3D axes automatically");
       view_butt[25]->type(FL_TOGGLE_BUTTON);
       view_butt[25]->down_box(GMSH_TOGGLE_BOX);
       view_butt[25]->selection_color(GMSH_TOGGLE_COLOR);
-      view_butt[25]->callback(activate_cb, (void*)"view_axes_auto_3d");
+      view_butt[25]->callback(view_options_ok_cb, (void*)"view_axes_auto_3d");
       
       view_value[13] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 6 * BH, IW / 3, BH);
+      view_value[13]->callback(view_options_ok_cb);
       view_value[14] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 6 * BH, IW / 3, BH);
+      view_value[14]->callback(view_options_ok_cb);
       view_value[15] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 6 * BH, IW / 3, BH, "3D Axes minimum");
       view_value[15]->align(FL_ALIGN_RIGHT);
+      view_value[15]->callback(view_options_ok_cb);
 
       view_value[16] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW / 3, BH);
+      view_value[16]->callback(view_options_ok_cb);
       view_value[17] = new Fl_Value_Input(L + 2 * WB + IW / 3, 2 * WB + 7 * BH, IW / 3, BH);
+      view_value[17]->callback(view_options_ok_cb);
       view_value[18] = new Fl_Value_Input(L + 2 * WB + 2 * IW / 3, 2 * WB + 7 * BH, IW / 3, BH, "3D Axes maximum");
       view_value[18]->align(FL_ALIGN_RIGHT);
+      view_value[18]->callback(view_options_ok_cb);
 
-      view_butt[7] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW / 2 - WB, BH, "Set position and size of 2D axes automatically");
+      view_butt[7] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 8 * BH, BW, BH, "Set position and size of 2D axes automatically");
       view_butt[7]->type(FL_TOGGLE_BUTTON);
       view_butt[7]->down_box(GMSH_TOGGLE_BOX);
       view_butt[7]->selection_color(GMSH_TOGGLE_COLOR);
-      view_butt[7]->callback(activate_cb, (void*)"view_axes_auto_2d");
+      view_butt[7]->callback(view_options_ok_cb, (void*)"view_axes_auto_2d");
       
       view_value[20] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 9 * BH, IW / 2, BH);
       view_value[20]->minimum(-1024);
       view_value[20]->maximum(1024);
       view_value[20]->step(1);
+      view_value[20]->callback(view_options_ok_cb);
       view_value[21] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 9 * BH, IW / 2, BH, "2D axes position");
       view_value[21]->align(FL_ALIGN_RIGHT);
       view_value[21]->minimum(-1024);
       view_value[21]->maximum(1024);
       view_value[21]->step(1);
+      view_value[21]->callback(view_options_ok_cb);
 
       view_value[22] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW / 2, BH);
       view_value[22]->minimum(0);
       view_value[22]->maximum(1024);
       view_value[22]->step(1);
+      view_value[22]->callback(view_options_ok_cb);
       view_value[23] = new Fl_Value_Input(L + 2 * WB + IW / 2, 2 * WB + 10 * BH, IW / 2, BH, "2D axes size");
       view_value[23]->align(FL_ALIGN_RIGHT);
       view_value[23]->minimum(0);
       view_value[23]->maximum(1024);
       view_value[23]->step(1);
+      view_value[23]->callback(view_options_ok_cb);
 
       o->end();
     }
@@ -2909,11 +3033,12 @@ void GUI::create_option_window()
       Fl_Group *o = new Fl_Group(L + WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Visibility");
       o->hide();
 
-      view_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW / 2 - WB, BH, "Show value scale");
+      view_butt[4] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 1 * BH, BW, BH, "Show value scale");
       view_butt[4]->tooltip("(Alt+i)");
       view_butt[4]->type(FL_TOGGLE_BUTTON);
       view_butt[4]->down_box(GMSH_TOGGLE_BOX);
       view_butt[4]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[4]->callback(view_options_ok_cb);
 
       static Fl_Menu_Item time_display[] = {
 	{"None", 0, 0, 0},
@@ -2926,17 +3051,20 @@ void GUI::create_option_window()
       view_choice[12] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Time display mode");
       view_choice[12]->menu(time_display);
       view_choice[12]->align(FL_ALIGN_RIGHT);
+      view_choice[12]->callback(view_options_ok_cb);
 
-      view_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW / 2 - WB, BH, "Show annotations");
+      view_butt[5] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Show annotations");
       view_butt[5]->tooltip("(Alt+n)");
       view_butt[5]->type(FL_TOGGLE_BUTTON);
       view_butt[5]->down_box(GMSH_TOGGLE_BOX);
       view_butt[5]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[5]->callback(view_options_ok_cb);
 
-      view_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW / 2 - WB, BH, "Draw element outlines");
+      view_butt[10] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Draw element outlines");
       view_butt[10]->type(FL_TOGGLE_BUTTON);
       view_butt[10]->down_box(GMSH_TOGGLE_BOX);
       view_butt[10]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[10]->callback(view_options_ok_cb);
 
       static Fl_Menu_Item menu_view_element_types[] = {
 	{"Points",      0, 0, 0, FL_MENU_TOGGLE},
@@ -2952,6 +3080,7 @@ void GUI::create_option_window()
 
       view_menu_butt[1] = new Fl_Menu_Button(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Elements");
       view_menu_butt[1]->menu(menu_view_element_types);
+      view_menu_butt[1]->callback(view_options_ok_cb);
       
       static Fl_Menu_Item menu_boundary[] = {
 	{"None", 0, 0, 0},
@@ -2963,18 +3092,21 @@ void GUI::create_option_window()
       view_choice[9] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Element boundary mode");
       view_choice[9]->menu(menu_boundary);
       view_choice[9]->align(FL_ALIGN_RIGHT);
+      view_choice[9]->callback(view_options_ok_cb);
 
       view_value[0] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Normals");
       view_value[0]->minimum(0);
       view_value[0]->maximum(500);
       view_value[0]->step(1);
       view_value[0]->align(FL_ALIGN_RIGHT);
+      view_value[0]->callback(view_options_ok_cb);
 
       view_value[1] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Tangents");
       view_value[1]->minimum(0);
       view_value[1]->maximum(500);
       view_value[1]->step(1);
       view_value[1]->align(FL_ALIGN_RIGHT);
+      view_value[1]->callback(view_options_ok_cb);
 
       static Fl_Menu_Item menu_view_field_types[] = {
 	{"Scalar", 0, 0, 0, FL_MENU_TOGGLE},
@@ -2985,6 +3117,7 @@ void GUI::create_option_window()
 
       view_menu_butt[0] = new Fl_Menu_Button(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Fields");
       view_menu_butt[0]->menu(menu_view_field_types);
+      view_menu_butt[0]->callback(view_options_ok_cb);
 
       view_value[33] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Maximum recursion level");
       view_value[33]->align(FL_ALIGN_RIGHT);
@@ -2992,12 +3125,14 @@ void GUI::create_option_window()
       view_value[33]->maximum(MAX_LEVEL_OF_ZOOM);
       view_value[33]->step(1);
       view_value[33]->value(0);
+      view_value[33]->callback(view_options_ok_cb);
 
       view_value[34] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Target error");
       view_value[34]->align(FL_ALIGN_RIGHT);
       view_value[34]->minimum(0);
       view_value[34]->maximum(1);
       view_value[34]->value(1.e-2);
+      view_value[34]->callback(view_options_ok_cb);
 
       o->end();
     }
@@ -3011,22 +3146,34 @@ void GUI::create_option_window()
       int ss = 2*IW/3/3+4;
 
       view_value[51] = new Fl_Value_Input(L + 2 * WB       , 2 * WB + 2 * BH, ss, BH);
+      view_value[51]->callback(view_options_ok_cb);
       view_value[52] = new Fl_Value_Input(L + 2 * WB + ss  , 2 * WB + 2 * BH, ss, BH);
+      view_value[52]->callback(view_options_ok_cb);
       view_value[53] = new Fl_Value_Input(L + 2 * WB + 2*ss, 2 * WB + 2 * BH, ss, BH, " X");
+      view_value[53]->callback(view_options_ok_cb);
       view_value[40] = new Fl_Value_Input(L + 2 * WB + IW  , 2 * WB + 2 * BH, 7*IW/10, BH);
       view_value[40]->align(FL_ALIGN_RIGHT);
+      view_value[40]->callback(view_options_ok_cb);
 
       view_value[54] = new Fl_Value_Input(L + 2 * WB       , 2 * WB + 3 * BH, ss, BH);
+      view_value[54]->callback(view_options_ok_cb);
       view_value[55] = new Fl_Value_Input(L + 2 * WB + ss  , 2 * WB + 3 * BH, ss, BH);
+      view_value[55]->callback(view_options_ok_cb);
       view_value[56] = new Fl_Value_Input(L + 2 * WB + 2*ss, 2 * WB + 3 * BH, ss, BH, " Y +");
+      view_value[56]->callback(view_options_ok_cb);
       view_value[41] = new Fl_Value_Input(L + 2 * WB + IW  , 2 * WB + 3 * BH, 7*IW/10, BH);
       view_value[41]->align(FL_ALIGN_RIGHT);
+      view_value[41]->callback(view_options_ok_cb);
 
       view_value[57] = new Fl_Value_Input(L + 2 * WB       , 2 * WB + 4 * BH, ss, BH);
+      view_value[57]->callback(view_options_ok_cb);
       view_value[58] = new Fl_Value_Input(L + 2 * WB + ss  , 2 * WB + 4 * BH, ss, BH);
+      view_value[58]->callback(view_options_ok_cb);
       view_value[59] = new Fl_Value_Input(L + 2 * WB + 2*ss, 2 * WB + 4 * BH, ss, BH, " Z");
+      view_value[59]->callback(view_options_ok_cb);
       view_value[42] = new Fl_Value_Input(L + 2 * WB + IW  , 2 * WB + 4 * BH, 7*IW/10, BH);
       view_value[42]->align(FL_ALIGN_RIGHT);
+      view_value[59]->callback(view_options_ok_cb);
       for(int i = 51; i <= 59; i++){
 	view_value[i]->minimum(-1.);
 	view_value[i]->maximum(1.);
@@ -3039,34 +3186,43 @@ void GUI::create_option_window()
 
       view_value[43] = new Fl_Value_Input(L + 2 * WB + 2 * IW-WB, 2 * WB + 2 * BH, 7*IW/10, BH, "X");
       view_value[43]->align(FL_ALIGN_RIGHT);
+      view_value[43]->callback(view_options_ok_cb);
 
       view_value[44] = new Fl_Value_Input(L + 2 * WB + 2 * IW-WB, 2 * WB + 3 * BH, 7*IW/10, BH, "Y");
       view_value[44]->align(FL_ALIGN_RIGHT);
+      view_value[44]->callback(view_options_ok_cb);
 
       view_value[45] = new Fl_Value_Input(L + 2 * WB + 2 * IW-WB, 2 * WB + 4 * BH, 7*IW/10, BH, "Z");
       view_value[45]->align(FL_ALIGN_RIGHT);
+      view_value[45]->callback(view_options_ok_cb);
 
       view_butt[6] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 5 * BH, BW, BH, "Use general transformation expressions");
       view_butt[6]->type(FL_TOGGLE_BUTTON);
       view_butt[6]->down_box(GMSH_TOGGLE_BOX);
       view_butt[6]->selection_color(GMSH_TOGGLE_COLOR);
       view_butt[6]->callback(activate_cb, (void*)"general_transform");
+      view_butt[6]->callback(view_options_ok_cb);
 
       view_choice[11] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Data source");
       view_choice[11]->align(FL_ALIGN_RIGHT);
       view_choice[11]->add("Self");
+      view_choice[11]->callback(view_options_ok_cb);
 
       view_value[2] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 7 * BH, IW, BH, "Factor");
       view_value[2]->align(FL_ALIGN_RIGHT);
+      view_value[2]->callback(view_options_ok_cb);
 
       view_input[4] = new Fl_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "X expression");
       view_input[4]->align(FL_ALIGN_RIGHT);
+      view_input[4]->callback(view_options_ok_cb);
 
       view_input[5] = new Fl_Input(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Y expression");
       view_input[5]->align(FL_ALIGN_RIGHT);
+      view_input[5]->callback(view_options_ok_cb);
 
       view_input[6] = new Fl_Input(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Z expression");
       view_input[6]->align(FL_ALIGN_RIGHT);
+      view_input[6]->callback(view_options_ok_cb);
 
       o->end();
     }
@@ -3079,26 +3235,31 @@ void GUI::create_option_window()
       view_value[12]->step(0.01);
       view_value[12]->maximum(1.);
       view_value[12]->align(FL_ALIGN_RIGHT);
+      view_value[12]->callback(view_options_ok_cb);
 
       view_choice[5] = new Fl_Choice(L + 2 * WB, 2 * WB + 2 * BH, IW, BH, "Point display");
       view_choice[5]->menu(menu_point_display);
       view_choice[5]->align(FL_ALIGN_RIGHT);
+      view_choice[5]->callback(view_options_ok_cb);
 
       view_value[61] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Point size");
       view_value[61]->minimum(0.1);
       view_value[61]->maximum(50);
       view_value[61]->step(0.1);
       view_value[61]->align(FL_ALIGN_RIGHT);
+      view_value[61]->callback(view_options_ok_cb);
 
       view_choice[6] = new Fl_Choice(L + 2 * WB, 2 * WB + 4 * BH, IW, BH, "Line display");
       view_choice[6]->menu(menu_line_display);
       view_choice[6]->align(FL_ALIGN_RIGHT);
+      view_choice[6]->callback(view_options_ok_cb);
 
       view_value[62] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Line width");
       view_value[62]->minimum(0.1);
       view_value[62]->maximum(50);
       view_value[62]->step(0.1);
       view_value[62]->align(FL_ALIGN_RIGHT);
+      view_value[62]->callback(view_options_ok_cb);
 
       {
         view_vector = new Fl_Group(L + 2 * WB, 2 * WB + 6 * BH, width - 2 * WB, 4 * BH, 0);
@@ -3114,6 +3275,7 @@ void GUI::create_option_window()
         view_choice[2] = new Fl_Choice(L + 2 * WB, 2 * WB + 6 * BH, IW, BH, "Vector display");
         view_choice[2]->menu(menu_vectype);
         view_choice[2]->align(FL_ALIGN_RIGHT);
+	view_choice[2]->callback(view_options_ok_cb);
 
 	view_push_butt[0] = new Fl_Button(L + 2 * IW - 2 * WB, 2 * WB + 6 * BH, (int)(1.5*BB), BH, "Edit arrow shape");
         view_push_butt[0]->callback(view_arrow_param_cb);
@@ -3123,55 +3285,58 @@ void GUI::create_option_window()
         view_value[60]->maximum(500);
         view_value[60]->step(1);
         view_value[60]->align(FL_ALIGN_RIGHT);
+	view_value[60]->callback(view_options_ok_cb);
 
 	view_butt[0] = new Fl_Check_Button(L + 2 * IW - 2 * WB, 2 * WB + 7 * BH, (int)(1.5*BB), BH, "Proportional");
 	view_butt[0]->type(FL_TOGGLE_BUTTON);
 	view_butt[0]->down_box(GMSH_TOGGLE_BOX);
 	view_butt[0]->selection_color(GMSH_TOGGLE_COLOR);
+	view_butt[0]->callback(view_options_ok_cb);
 
         view_value[63] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 8 * BH, IW, BH, "Displacement factor");
         view_value[63]->minimum(0.);
         view_value[63]->maximum(1.);
         view_value[63]->step(0.01);
         view_value[63]->align(FL_ALIGN_RIGHT);
+	view_value[63]->callback(view_options_ok_cb);
 
         view_choice[10] = new Fl_Choice(L + 2 * WB, 2 * WB + 9 * BH, IW, BH, "Data source");
         view_choice[10]->align(FL_ALIGN_RIGHT);
 	view_choice[10]->add("Self");
-
-        
+	view_choice[10]->callback(view_options_ok_cb);
 
         view_vector->end();
-
-        static Fl_Menu_Item menu_vecloc[] = {
-          {"Barycenter", 0, 0, 0},
-          {"Vertex", 0, 0, 0},
-          {0}
-        };
-        view_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Glyph location");
-        view_choice[3]->menu(menu_vecloc);
-        view_choice[3]->align(FL_ALIGN_RIGHT);
-
-	static Fl_Menu_Item menu_tensor[] = {
-	  {"Von-Mises", 0, 0, 0},
-          {"LMGC90", 0, 0, 0}, 
-          {"LMGC90 Type", 0, 0, 0}, 
-          {"LMGC90 Coordinance", 0, 0, 0}, 
-          {"LMGC90 Pression", 0, 0, 0}, 
-          {"LMGC90 Normal stress", 0, 0, 0}, 
-          {"LMGC90 X displacement", 0, 0, 0}, 
-          {"LMGC90 Y displacement", 0, 0, 0}, 
-          {"LMGC90 Z displacement", 0, 0, 0}, 
-          {"LMGC90 Average displacement", 0, 0, 0}, 
-          {"LMGC90 Norm of displacement", 0, 0, 0}, 
-          {0}
-        };
-        view_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Tensor display");
-        view_choice[4]->menu(menu_tensor);
-        view_choice[4]->align(FL_ALIGN_RIGHT);
-
       }
 
+      static Fl_Menu_Item menu_vecloc[] = {
+	{"Barycenter", 0, 0, 0},
+	{"Vertex", 0, 0, 0},
+	{0}
+      };
+      view_choice[3] = new Fl_Choice(L + 2 * WB, 2 * WB + 10 * BH, IW, BH, "Glyph location");
+      view_choice[3]->menu(menu_vecloc);
+      view_choice[3]->align(FL_ALIGN_RIGHT);
+      view_choice[3]->callback(view_options_ok_cb);
+      
+      static Fl_Menu_Item menu_tensor[] = {
+	{"Von-Mises", 0, 0, 0},
+	{"LMGC90", 0, 0, 0}, 
+	{"LMGC90 Type", 0, 0, 0}, 
+	{"LMGC90 Coordinance", 0, 0, 0}, 
+	{"LMGC90 Pression", 0, 0, 0}, 
+	{"LMGC90 Normal stress", 0, 0, 0}, 
+	{"LMGC90 X displacement", 0, 0, 0}, 
+	{"LMGC90 Y displacement", 0, 0, 0}, 
+	{"LMGC90 Z displacement", 0, 0, 0}, 
+	{"LMGC90 Average displacement", 0, 0, 0}, 
+	{"LMGC90 Norm of displacement", 0, 0, 0}, 
+	{0}
+      };
+      view_choice[4] = new Fl_Choice(L + 2 * WB, 2 * WB + 11 * BH, IW, BH, "Tensor display");
+      view_choice[4]->menu(menu_tensor);
+      view_choice[4]->align(FL_ALIGN_RIGHT);
+      view_choice[4]->callback(view_options_ok_cb);
+
       o->end();
     }
     {
@@ -3183,28 +3348,32 @@ void GUI::create_option_window()
       view_butt[11]->type(FL_TOGGLE_BUTTON);
       view_butt[11]->down_box(GMSH_TOGGLE_BOX);
       view_butt[11]->selection_color(GMSH_TOGGLE_COLOR);
-      view_butt[11]->callback(activate_cb, (void*)"view_light");
+      view_butt[11]->callback(view_options_ok_cb, (void*)"view_light");
 
       view_butt[8] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Enable lighting of lines");
       view_butt[8]->type(FL_TOGGLE_BUTTON);
       view_butt[8]->down_box(GMSH_TOGGLE_BOX);
       view_butt[8]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[8]->callback(view_options_ok_cb);
 
       view_butt[9] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 3 * BH, BW, BH, "Use two-side lighting");
       view_butt[9]->type(FL_TOGGLE_BUTTON);
       view_butt[9]->down_box(GMSH_TOGGLE_BOX);
       view_butt[9]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[9]->callback(view_options_ok_cb);
 
       view_butt[12] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 4 * BH, BW, BH, "Smooth normals");
       view_butt[12]->type(FL_TOGGLE_BUTTON);
       view_butt[12]->down_box(GMSH_TOGGLE_BOX);
       view_butt[12]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[12]->callback(view_options_ok_cb);
 
       view_value[10] = new Fl_Value_Input(L + 2 * WB, 2 * WB + 5 * BH, IW, BH, "Smoothing threshold angle");
       view_value[10]->minimum(0.);
       view_value[10]->step(1.);
       view_value[10]->maximum(180.);
       view_value[10]->align(FL_ALIGN_RIGHT);
+      view_value[10]->callback(view_options_ok_cb);
       
       o->end();
     }
@@ -3216,11 +3385,13 @@ void GUI::create_option_window()
       view_butt[24]->type(FL_TOGGLE_BUTTON);
       view_butt[24]->down_box(GMSH_TOGGLE_BOX);
       view_butt[24]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[24]->callback(view_options_ok_cb);
 
       view_butt[26] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 2 * BH, BW, BH, "Stipple curves in 2D plots");
       view_butt[26]->type(FL_TOGGLE_BUTTON);
       view_butt[26]->down_box(GMSH_TOGGLE_BOX);
       view_butt[26]->selection_color(GMSH_TOGGLE_COLOR);
+      view_butt[26]->callback(view_options_ok_cb);
       
       Fl_Scroll *s = new Fl_Scroll(L + 2 * WB, 3 * WB + 3 * BH, IW + 20, height - 5 * WB - 3 * BH);
       int i = 0;
@@ -3239,6 +3410,7 @@ void GUI::create_option_window()
 
       view_colorbar_window = new Colorbar_Window(L + 2 * WB, 2 * WB + BH, width - 4 * WB, height - 4 * WB - BH);
       view_colorbar_window->end();
+      view_colorbar_window->callback(view_options_ok_cb);
 
       o->end();
     }
@@ -3424,7 +3596,7 @@ void GUI::update_view_window(int num)
 
   opt_view_external_view(num, GMSH_GUI, 0);
   opt_view_glyph_location(num, GMSH_GUI, 0);
-  //opt_view_tensor_type(num, GMSH_GUI, 0);
+  opt_view_tensor_type(num, GMSH_GUI, 0);
 
   opt_view_fake_transparency(num, GMSH_GUI, 0);
   opt_view_use_stipple(num, GMSH_GUI, 0);
@@ -4563,24 +4735,23 @@ void GUI::create_solver_window(int num)
 
       solver[num].input[2] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, LL, BH, "Executable");
       solver[num].input[2]->align(FL_ALIGN_RIGHT);
+      solver[num].input[2]->callback(solver_ok_cb);
+
       Fl_Button *b = new Fl_Button(2 * WB, 3 * WB + 2 * BH, BB, BH, "Choose");
       b->callback(solver_choose_executable_cb, (void *)num);
 
       solver[num].butt[2] = new Fl_Check_Button(2 * WB, 4 * WB + 3 * BH, LL, BH, "Enable client-server connection");
+      solver[num].butt[2]->callback(solver_ok_cb);
       solver[num].butt[0] = new Fl_Check_Button(2 * WB, 4 * WB + 4 * BH, LL, BH, "Display client messages");
+      solver[num].butt[0]->callback(solver_ok_cb);
       solver[num].butt[1] = new Fl_Check_Button(2 * WB, 4 * WB + 5 * BH, LL, BH, "Merge views automatically");
+      solver[num].butt[1]->callback(solver_ok_cb);
       for(i = 0; i < 3; i++) {
         solver[num].butt[i]->type(FL_TOGGLE_BUTTON);
         solver[num].butt[i]->down_box(GMSH_TOGGLE_BOX);
         solver[num].butt[i]->selection_color(GMSH_TOGGLE_COLOR);
       }
 
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - 2 * BB - 3 * WB, 
-						   height - (3 + newrow) * WB - (2 + newrow) * BH, 
-						   BB, BH, "Apply");
-        o->callback(solver_ok_cb, (void *)num);
-      }
       {
         Fl_Button *o = new Fl_Button(width - BB - 2 * WB,
                                      height - (3 + newrow) * WB - (2 + newrow) * BH,
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index f525b0cfa8..0f3bc4bdde 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -161,6 +161,7 @@ public:
   // Option window
   Fl_Window        *opt_window;
   Fl_Hold_Browser  *opt_browser;
+  Fl_Return_Button *opt_redraw;
 
   // general options
   Fl_Group         *gen_group;
diff --git a/doc/VERSIONS b/doc/VERSIONS
index a08b89b977..9ba8730efc 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,10 +1,10 @@
-$Id: VERSIONS,v 1.363 2006-08-25 19:27:46 geuzaine Exp $
+$Id: VERSIONS,v 1.364 2006-08-26 17:00:25 geuzaine Exp $
 
 2.0: new geometry and mesh databases; complete rewrite of geometry and
 mesh drawing code; complete rewrite of the input/output code (new
 binary mesh format, improved support for STL, MESH, VRML and UNV
-formats); new 2D mesh algorithm; lots of small improvements all over
-the place.
+formats); new 2D mesh algorithm; option changes in the interface are
+now applied instantenously; lots of improvements all over the place.
 
 1.66: added support for offscreen rendering using OSMesa; added
 support for SVG output;
-- 
GitLab