diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index b9a6fa62667f216ef00e99ba440d122bdff8a641..5d285fe61792d935fbc94f2398e5a80ca0d12658 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.231 2004-05-17 17:40:02 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.232 2004-05-18 04:54:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -222,38 +222,38 @@ int SetGlobalShortcut(int event)
   return WID->global_shortcuts(event);
 }
 
-int SelectContour(int type, int num, List_T * Liste1)
+int SelectContour(int type, int num, List_T * List1)
 {
   int k = 0, ip, i;
 
-  if(!List_Nbr(Liste1)) {
+  if(!List_Nbr(List1)) {
     switch (type) {
     case ENT_LINE:
-      k = alledgeslinked(num, Liste1, (List_T *) NULL);
+      k = alledgeslinked(num, List1, (List_T *) NULL);
       break;
     case ENT_SURFACE:
-      k = allfaceslinked(num, Liste1, (List_T *) NULL);
+      k = allfaceslinked(num, List1, (List_T *) NULL);
       break;
     }
   }
   else {
-    List_T *Liste2 = List_Create(1, 1, sizeof(int));
-    for(i = 0; i < List_Nbr(Liste1); i++)
-      List_Add(Liste2, List_Pointer(Liste1, i));
-    List_Reset(Liste1);
+    List_T *List2 = List_Create(1, 1, sizeof(int));
+    for(i = 0; i < List_Nbr(List1); i++)
+      List_Add(List2, List_Pointer(List1, i));
+    List_Reset(List1);
     switch (type) {
     case ENT_LINE:
-      k = alledgeslinked(num, Liste1, Liste2);
+      k = alledgeslinked(num, List1, List2);
       break;
     case ENT_SURFACE:
-      k = allfaceslinked(num, Liste1, Liste2);
+      k = allfaceslinked(num, List1, List2);
       break;
     }
-    List_Delete(Liste2);
+    List_Delete(List2);
   }
 
-  for(i = 0; i < List_Nbr(Liste1); i++) {
-    List_Read(Liste1, i, &ip);
+  for(i = 0; i < List_Nbr(List1); i++) {
+    List_Read(List1, i, &ip);
     switch (type) {
     case ENT_LINE:
       HighlightEntityNum(0, abs(ip), 0, 1);
@@ -1003,16 +1003,15 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
     Draw();
   }
 
-  Msg(STATUS3N, "Select point ('q'=quit)");
-  ib = SelectEntity(ENT_POINT, &v, &c, &s);
-  if(ib == 1) {
+  Msg(STATUS3N, "Select point ('q'=abort)");
+  char ib = SelectEntity(ENT_POINT, &v, &c, &s);
+  if(ib == 'l') {
     // This would bypass the "Apply" button... Not necessarily bad,
     // but it's not consistent with the rest of the GUI.
     //opt_general_rotation_center0(0, GMSH_SET|GMSH_GUI, v->Pos.X);
@@ -1766,8 +1765,7 @@ static void _new_multiline(int type)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
-  static int n, p[100];
+  int n, p[100];
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -1776,12 +1774,12 @@ static void _new_multiline(int type)
 
   n = 0;
   while(1) {
-    Msg(STATUS3N, "Select point ('e'=end, 'q'=quit)");
-    ib = SelectEntity(ENT_POINT, &v, &c, &s);
-    if(ib == 1) {       /* left mouse butt */
+    Msg(STATUS3N, "Select points ('e'=end, 'u'=undo, 'q'=abort)");
+    char ib = SelectEntity(ENT_POINT, &v, &c, &s);
+    if(ib == 'l') {
       p[n++] = v->Num;
     }
-    if(ib == -1) {      /* 'e' */
+    if(ib == 'e') {
       if(n >= 2) {
         switch (type) {
         case 0:
@@ -1798,12 +1796,18 @@ static void _new_multiline(int type)
           break;
         }
       }
-      n = 0;
       ZeroHighlight(THEM);
       Draw();
-    }
-    if(ib == 0) {       /* 'q' */
       n = 0;
+    }
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0);
+	Draw(); // inefficient, but hard to do otherwise
+	n--;
+      }
+    }
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
@@ -1822,8 +1826,7 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
-  static int n, p[100];
+  int n, p[100];
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -1833,15 +1836,21 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
   n = 0;
   while(1) {
     if(n == 0)
-      Msg(STATUS3N, "Select start point ('q'=quit)");
+      Msg(STATUS3N, "Select start point ('u'=undo, 'q'=abort)");
     if(n == 1)
-      Msg(STATUS3N, "Select end point ('q'=quit)");
-    ib = SelectEntity(ENT_POINT, &v, &c, &s);
-    if(ib == 1) {       /* left mouse butt */
+      Msg(STATUS3N, "Select end point ('u'=undo, 'q'=abort)");
+    char ib = SelectEntity(ENT_POINT, &v, &c, &s);
+    if(ib == 'l') {
       p[n++] = v->Num;
     }
-    if(ib == 0) {       /* 'q' */
-      n = 0;
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0);
+	Draw(); // inefficient, but hard to do otherwise
+	n--;
+      }
+    }
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
@@ -1871,8 +1880,7 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
-  static int n, p[100];
+  int n, p[100];
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -1882,17 +1890,23 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
   n = 0;
   while(1) {
     if(n == 0)
-      Msg(STATUS3N, "Select start point ('q'=quit)");
+      Msg(STATUS3N, "Select start point ('u'=undo, 'q'=abort)");
     if(n == 1)
-      Msg(STATUS3N, "Select center point ('q'=quit)");
+      Msg(STATUS3N, "Select center point ('u'=undo, 'q'=abort)");
     if(n == 2)
-      Msg(STATUS3N, "Select end point ('q'=quit)");
-    ib = SelectEntity(ENT_POINT, &v, &c, &s);
-    if(ib == 1) {       /* left mouse butt */
+      Msg(STATUS3N, "Select end point ('u'=undo, 'q'=abort)");
+    char ib = SelectEntity(ENT_POINT, &v, &c, &s);
+    if(ib == 'l') {
       p[n++] = v->Num;
     }
-    if(ib == 0) {       /* 'q' */
-      n = 0;
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0);
+	Draw(); // inefficient, but hard to do otherwise
+	n--;
+      }
+    }
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
@@ -1912,8 +1926,7 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
-  static int n, p[100];
+  int n, p[100];
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -1923,19 +1936,25 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
   n = 0;
   while(1) {
     if(n == 0)
-      Msg(STATUS3N, "Select start point ('q'=quit)");
+      Msg(STATUS3N, "Select start point ('u'=undo, 'q'=abort)");
     if(n == 1)
-      Msg(STATUS3N, "Select center point ('q'=quit)");
+      Msg(STATUS3N, "Select center point ('u'=undo, 'q'=abort)");
     if(n == 2)
-      Msg(STATUS3N, "Select major axis point ('q'=quit)");
+      Msg(STATUS3N, "Select major axis point ('u'=undo, 'q'=abort)");
     if(n == 3)
-      Msg(STATUS3N, "Select end point ('q'=quit)");
-    ib = SelectEntity(ENT_POINT, &v, &c, &s);
-    if(ib == 1) {       /* left mouse butt */
+      Msg(STATUS3N, "Select end point ('u'=undo, 'q'=abort)");
+    char ib = SelectEntity(ENT_POINT, &v, &c, &s);
+    if(ib == 'l') {
       p[n++] = v->Num;
     }
-    if(ib == 0) {       /* 'q' */
-      n = 0;
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0);
+	Draw(); // inefficient, but hard to do otherwise
+	n--;
+      }
+    }
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
@@ -1955,11 +1974,11 @@ static void _new_surface_volume(int mode)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib, type, zone;
-  List_T *Liste1, *Liste2;
+  int type, num;
 
-  Liste1 = List_Create(10, 10, sizeof(int));
-  Liste2 = List_Create(10, 10, sizeof(int));
+  List_T *List1 = List_Create(10, 10, sizeof(int));
+  List_T *List2 = List_Create(10, 10, sizeof(int));
+  List_T *ListUnsorted = List_Create(10, 10, sizeof(int));
 
   if(mode == 2) {
     type = ENT_SURFACE;
@@ -1977,64 +1996,115 @@ static void _new_surface_volume(int mode)
   }
 
   while(1) {
-    List_Reset(Liste1);
-    List_Reset(Liste2);
+    List_Reset(List1);
+    List_Reset(List2);
+    List_Reset(ListUnsorted);
 
     while(1) {
-      Msg(STATUS3N, "Select exterior boundary ('q'=quit)");
-      ib = SelectEntity(type, &v, &c, &s);
-      if(ib <= 0) {
+      Msg(STATUS3N, "Select exterior boundary ('u'=undo, 'q'=abort)");
+      char ib = SelectEntity(type, &v, &c, &s);
+      if(ib == 'q') {
         ZeroHighlight(THEM);
         Draw();
         goto stopall;
       }
-      if(SelectContour(type, (type == ENT_LINE) ? c->Num : s->Num, Liste1)) {
-        if(type == ENT_LINE)
-          add_loop(Liste1, CTX.filename, &zone);
-        else
-          add_vol(Liste1, CTX.filename, &zone);
-        List_Reset(Liste1);
-        List_Add(Liste2, &zone);
-        while(1) {
-          Msg(STATUS3N, "Select hole boundary ('q'=quit)");
-          ib = SelectEntity(type, &v, &c, &s);
-          if(ib <= 0) {
-            ZeroHighlight(THEM);
-            Draw();
-            break;
-          }
-          if(SelectContour
-             (type, (type == ENT_LINE) ? c->Num : s->Num, Liste1)) {
-            if(type == ENT_LINE)
-              add_loop(Liste1, CTX.filename, &zone);
-            else
-              add_vol(Liste1, CTX.filename, &zone);
-            List_Reset(Liste1);
-            List_Add(Liste2, &zone);
-          }
-        }
-        if(List_Nbr(Liste2)) {
-          switch (mode) {
-          case 0:
-            add_surf(Liste2, CTX.filename, 0, 2);
-            break;
-          case 1:
-            add_surf(Liste2, CTX.filename, 0, 1);
-            break;
-          case 2:
-            add_multvol(Liste2, CTX.filename);
-            break;
-          }
-          ZeroHighlight(THEM);
-          Draw();
-          break;
-        }
+      if(ib == 'u') {
+	if(List_Nbr(ListUnsorted) > 0){
+	  for(int i = 0; i < List_Nbr(List1); i++){
+	    List_Read(List1, i, &num);	    
+	    ZeroHighlightEntityNum(0,
+				   (type == ENT_LINE) ? abs(num) : 0, 
+				   (type != ENT_LINE) ? abs(num) : 0);
+	  }
+	  List_Reset(List1);
+	  List_Pop(ListUnsorted);
+	  for(int i = 0; i < List_Nbr(ListUnsorted); i++){
+	    List_Read(ListUnsorted, i, &num);
+	    List_Add(List1, &num);
+	    HighlightEntityNum(0, 
+			       (type == ENT_LINE) ? abs(num) : 0, 
+			       (type != ENT_LINE) ? abs(num) : 0, 1);
+	  }
+	  Draw();
+	}
+      }
+      if(ib == 'l') {
+	int num = (type == ENT_LINE) ? c->Num : s->Num;
+	List_Add(ListUnsorted, &num);
+	if(SelectContour(type, num, List1)) {
+	  if(type == ENT_LINE)
+	    add_loop(List1, CTX.filename, &num);
+	  else
+	    add_vol(List1, CTX.filename, &num);
+	  List_Reset(List1);
+	  List_Reset(ListUnsorted);
+	  List_Add(List2, &num);
+	  while(1) {
+	    Msg(STATUS3N, "Select hole boundaries ('e'=end, 'u'=undo, 'q'=abort)");
+	    ib = SelectEntity(type, &v, &c, &s);
+	    if(ib == 'q') {
+	      ZeroHighlight(THEM);
+	      Draw();
+	      goto stopall;
+	    }
+	    if(ib == 'e') {
+	      ZeroHighlight(THEM);
+	      Draw();
+	      break;
+	    }
+	    if(ib == 'u') {
+	      if(List_Nbr(ListUnsorted) > 0){
+		for(int i = 0; i < List_Nbr(List1); i++){
+		  List_Read(List1, i, &num);	    
+		  ZeroHighlightEntityNum(0,
+					 (type == ENT_LINE) ? abs(num) : 0, 
+					 (type != ENT_LINE) ? abs(num) : 0);
+		}
+		List_Reset(List1);
+		List_Pop(ListUnsorted);
+		for(int i = 0; i < List_Nbr(ListUnsorted); i++){
+		  List_Read(ListUnsorted, i, &num);
+		  List_Add(List1, &num);
+		  HighlightEntityNum(0, 
+				     (type == ENT_LINE) ? abs(num) : 0, 
+				     (type != ENT_LINE) ? abs(num) : 0, 1);
+		}
+		Draw();
+	      }
+	    }
+	    if(ib == 'l') {
+	      num = (type == ENT_LINE) ? c->Num : s->Num;
+	      List_Add(ListUnsorted, &num);
+	      if(SelectContour(type, num, List1)) {
+		if(type == ENT_LINE)
+		  add_loop(List1, CTX.filename, &num);
+		else
+		  add_vol(List1, CTX.filename, &num);
+		List_Reset(List1);
+		List_Reset(ListUnsorted);
+		List_Add(List2, &num);
+	      }
+	    }
+	  }
+	  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_multvol(List2, CTX.filename); break;
+	    }
+	    ZeroHighlight(THEM);
+	    Draw();
+	    break;
+	  }
+	} // if SelectContour
       }
     }
   }
+
 stopall:;
-  List_Delete(Liste1);
-  List_Delete(Liste2);
+  List_Delete(List1);
+  List_Delete(List2);
+  List_Delete(ListUnsorted);
   Msg(STATUS3N, "Ready");
 }
 
@@ -2059,9 +2129,11 @@ static void _transform_point_line_surface(int transfo, int mode, char *what)
   Curve *c;
   Surface *s;
   int type, num = 0;
+  char *str;
 
   if(!strcmp(what, "Point")) {
     type = ENT_POINT;
+    str = "points";
     if(!opt_geometry_points(0, GMSH_GET, 0)) {
       opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
@@ -2069,6 +2141,7 @@ static void _transform_point_line_surface(int transfo, int mode, char *what)
   }
   else if(!strcmp(what, "Line")) {
     type = ENT_LINE;
+    str = "lines";
     if(!opt_geometry_lines(0, GMSH_GET, 0)) {
       opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
@@ -2076,6 +2149,7 @@ static void _transform_point_line_surface(int transfo, int mode, char *what)
   }
   else {
     type = ENT_SURFACE;
+    str = "surfaces";
     if(!opt_geometry_surfaces(0, GMSH_GET, 0)) {
       opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
@@ -2083,48 +2157,80 @@ static void _transform_point_line_surface(int transfo, int mode, char *what)
   }
 
   while(1) {
-    Msg(STATUS3N, "Select %s ('q'=quit)", what);
-    if(!SelectEntity(type, &v, &c, &s)) {
+    Msg(STATUS3N, "Select %s ('q'=abort)", str);
+    char ib = SelectEntity(type, &v, &c, &s);
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
     }
-    switch (type) {
-    case ENT_POINT:
-      num = v->Num;
-      break;
-    case ENT_LINE:
-      num = c->Num;
-      break;
-    case ENT_SURFACE:
-      num = s->Num;
-      break;
-    }
-    switch (transfo) {
-    case 0:
-      translate(mode, num, CTX.filename, what);
-      break;
-    case 1:
-      rotate(mode, num, CTX.filename, what);
-      break;
-    case 2:
-      dilate(mode, num, CTX.filename, what);
-      break;
-    case 3:
-      symmetry(mode, num, CTX.filename, what);
-      break;
-    case 4:
-      extrude(num, CTX.filename, what);
-      break;
-    case 5:
-      protude(num, CTX.filename, what);
-      break;
-    case 6:
-      delet(num, CTX.filename, what);
-      break;
+    if(ib == 'l') {
+      switch (type) {
+      case ENT_POINT:
+	num = v->Num;
+	break;
+      case ENT_LINE:
+	num = c->Num;
+	break;
+      case ENT_SURFACE:
+	num = s->Num;
+	break;
+      }
+      switch (transfo) {
+      case 0:
+	translate(mode, num, 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, num, 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, num, 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, num, 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(num, 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(num, 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(num, CTX.filename, what);
+	break;
+      }
+      ZeroHighlight(THEM);
+      CalculateMinMax(THEM->Points, NULL);
+      Draw();
     }
-    ZeroHighlight(THEM);
-    Draw();
   }
   Msg(STATUS3N, "Ready");
 }
@@ -2389,11 +2495,13 @@ static void _add_physical(char *what)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib, type, zone;
-  List_T *Liste1;
+  int type, num;
+  char *str;
+  List_T *List1;
 
   if(!strcmp(what, "Point")) {
     type = ENT_POINT;
+    str = "points";
     if(!opt_geometry_points(0, GMSH_GET, 0)) {
       opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
@@ -2401,6 +2509,7 @@ static void _add_physical(char *what)
   }
   else if(!strcmp(what, "Line")) {
     type = ENT_LINE;
+    str = "lines";
     if(!opt_geometry_lines(0, GMSH_GET, 0)) {
       opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
@@ -2408,52 +2517,66 @@ static void _add_physical(char *what)
   }
   else if(!strcmp(what, "Surface")) {
     type = ENT_SURFACE;
+    str = "surfaces";
     if(!opt_geometry_surfaces(0, GMSH_GET, 0)) {
       opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
     }
   }
   else {
-    Msg(GERROR, "Interactive volume selection not done "
-        "(you will have to edit the input file manually)");
+    type = ENT_VOLUME;
+    str = "volumes";
     if(!opt_geometry_volumes(0, GMSH_GET, 0)) {
       opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
       Draw();
     }
+    Msg(GERROR, "Interactive volume selection not done "
+        "(you will have to edit the input file manually)");
     return;
   }
 
-  Liste1 = List_Create(5, 5, sizeof(int));
+  List1 = List_Create(5, 5, sizeof(int));
   while(1) {
-    Msg(STATUS3N, "Select %s ('e'=end, 'q'=quit)", what);
-    ib = SelectEntity(type, &v, &c, &s);
-    if(ib == 1) {       /* left mouse */
+    Msg(STATUS3N, "Select %s ('e'=end, 'u'=undo, 'q'=abort)", str);
+    char ib = SelectEntity(type, &v, &c, &s);
+    if(ib == 'l') {
       switch (type) {
       case ENT_POINT:
-        List_Add(Liste1, &v->Num);
+        List_Add(List1, &v->Num);
         break;
       case ENT_LINE:
-        List_Add(Liste1, &c->Num);
+        List_Add(List1, &c->Num);
         break;
       case ENT_SURFACE:
-        List_Add(Liste1, &s->Num);
+        List_Add(List1, &s->Num);
         break;
       }
     }
-    if(ib == -1) {      /* end */
-      if(List_Nbr(Liste1)) {
-        add_physical(Liste1, CTX.filename, type, &zone);
-        List_Reset(Liste1);
+    if(ib == 'u') {
+      if(List_Nbr(List1)) {
+	List_Read(List1, List_Nbr(List1)-1, &num);
+	ZeroHighlightEntityNum((type == ENT_POINT) ? num : 0,
+			       (type == ENT_LINE) ? num : 0,
+			       (type == ENT_SURFACE) ? num : 0);
+	Draw(); // inefficient, but hard to do otherwise
+	List_Pop(List1);
+      }
+    }
+    if(ib == 'e') {
+      if(List_Nbr(List1)) {
+        add_physical(List1, CTX.filename, type, &num);
+        List_Reset(List1);
         ZeroHighlight(THEM);
         Draw();
       }
     }
-    if(ib == 0) {
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
     }
   }
+  List_Delete(List1);
   Msg(STATUS3N, "Ready");
 }
 
@@ -2544,8 +2667,7 @@ void mesh_define_length_cb(CALLBACK_ARGS)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
-  static int n = 0, p[100];
+  int n = 0, p[100];
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -2555,22 +2677,26 @@ void mesh_define_length_cb(CALLBACK_ARGS)
   WID->create_mesh_context_window(0);
 
   while(1) {
-    Msg(STATUS3N, "Select point ('e'=end, 'q'=quit)");
-    ib = SelectEntity(ENT_POINT, &v, &c, &s);
-    if(ib == 1) {       /* left mouse butt */
+    Msg(STATUS3N, "Select points ('e'=end, 'u'=undo, 'q'=qbort)");
+    char ib = SelectEntity(ENT_POINT, &v, &c, &s);
+    if(ib == 'l') {
       p[n++] = v->Num;
     }
-    if(ib == -1) {      /* 'e' */
-      if(n >= 1) {
-        add_charlength(n, p, CTX.filename);
-        n = 0;
-        ZeroHighlight(THEM);
-        Draw();
-        break;
+    if(ib == 'e') {
+      if(n > 0)
+        add_charlength(n, p, CTX.filename, (char*)WID->context_mesh_input[0]->value());
+      ZeroHighlight(THEM);
+      Draw();
+      n = 0;
+    }
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(p[n-1], 0, 0);
+	Draw(); // inefficient, but hard to do otherwise
+	n--;
       }
     }
-    if(ib == 0) {       /* 'q' */
-      n = 0;
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
@@ -2584,8 +2710,7 @@ void mesh_define_recombine_cb(CALLBACK_ARGS)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib;
-  static int n, p[100];
+  int n, p[100];
 
   if(!opt_geometry_surfaces(0, GMSH_GET, 0)) {
     opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
@@ -2594,22 +2719,26 @@ void mesh_define_recombine_cb(CALLBACK_ARGS)
 
   n = 0;
   while(1) {
-    Msg(STATUS3N, "Select surface ('e'=end, 'q'=quit)");
-    ib = SelectEntity(ENT_SURFACE, &v, &c, &s);
-    if(ib == 1) {       /* left mouse butt */
+    Msg(STATUS3N, "Select surface ('e'=end, 'u'=undo, 'q'=qbort)");
+    char ib = SelectEntity(ENT_SURFACE, &v, &c, &s);
+    if(ib == 'l') {
       p[n++] = s->Num;
     }
-    if(ib == -1) {      /* 'e' */
-      if(n >= 1) {
+    if(ib == 'e') {
+      if(n > 0)
         add_recosurf(n, p, CTX.filename);
-        break;
-      }
-      n = 0;
       ZeroHighlight(THEM);
       Draw();
-    }
-    if(ib == 0) {       /* 'q' */
       n = 0;
+    }
+    if(ib == 'u') {
+      if(n > 0){
+	ZeroHighlightEntityNum(0, 0, p[n-1]);
+	Draw(); // inefficient, but hard to do otherwise
+	n--;
+      }
+    }
+    if(ib == 'q') {
       ZeroHighlight(THEM);
       Draw();
       break;
@@ -2628,8 +2757,8 @@ static void _add_transfinite(int dim)
   Vertex *v;
   Curve *c;
   Surface *s;
-  int ib = 0;
-  static int n, p[100];
+  char ib;
+  int n, p[100];
 
   if(!opt_geometry_points(0, GMSH_GET, 0)) {
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
@@ -2661,78 +2790,98 @@ static void _add_transfinite(int dim)
   while(1) {
     switch (dim) {
     case 1:
-      Msg(STATUS3N, "Select line ('e'=end, 'q'=quit)");
+      Msg(STATUS3N, "Select lines ('e'=end, 'u'=undo, 'q'=abort)");
       ib = SelectEntity(ENT_LINE, &v, &c, &s);
       break;
     case 2:
-      Msg(STATUS3N, "Select surface ('e'=end, 'q'=quit)");
+      Msg(STATUS3N, "Select surface ('q'=abort)");
       ib = SelectEntity(ENT_SURFACE, &v, &c, &s);
       break;
-    case 3:
-      ib = 1;
+    default:
+      ib = 'l';
+      break;
+    }
+
+    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(THEM);
+      Draw();
+      n = 0;
+    }
+    if(ib == 'u') {
+      if(dim == 1) {
+        if(n > 0){
+	  ZeroHighlightEntityNum(0, p[n-1], 0);
+	  Draw(); // inefficient, but hard to do otherwise
+	  n--;
+	}
+      }
+    }
+    if(ib == 'q') {
+      ZeroHighlight(THEM);
+      Draw();
       break;
     }
-    if(ib == 1) {       /* left mouse butt */
+    if(ib == 'l') {
       switch (dim) {
       case 1:
         p[n++] = c->Num;
         break;
       case 2:
-        p[n++] = s->Num;        // fall-through
+        p[n++] = s->Num; // fall-through
       case 3:
         while(1) {
-          Msg(STATUS3N, "Select point ('e'=end, 'q'=quit)");
+          Msg(STATUS3N, "Select points ('e'=end, 'u'=undo, 'q'=quit)");
           ib = SelectEntity(ENT_POINT, &v, &c, &s);
-          if(ib == 1) { /* left mouse butt */
+          if(ib == 'l') {
             p[n++] = v->Num;
           }
-          if(ib == -1) {        /* 'e' */
+	  if(ib == 'u') {
+	    if(n > ((dim == 2) ? 1 : 0)){
+	      ZeroHighlightEntityNum(p[n-1], 0, 0);
+	      Draw(); // inefficient, but hard to do otherwise
+	      n--;
+	    }
+	  }
+          if(ib == 'e') {
             switch (dim) {
             case 2:
               if(n == 3 + 1 || n == 4 + 1)
                 add_trsfsurf(n, p, CTX.filename);
               else
-                Msg(STATUS2,
-                    "Wrong number of points for transfinite surface");
+                Msg(STATUS2, "Wrong number of points for transfinite surface");
               break;
             case 3:
               if(n == 6 || n == 8)
-                add_trsfvol(n, p, CTX.filename);
+                add_trsfvol(n, p, CTX.filename, 
+			    (char*)WID->context_mesh_input[3]->value());
               else
                 Msg(STATUS2, "Wrong number of points for transfinite volume");
               break;
             }
-            n = 0;
             ZeroHighlight(THEM);
             Draw();
+            n = 0;
             break;
           }
-          if(ib == 0) { /* 'q' */
-            n = 0;
+          if(ib == 'q') {
             ZeroHighlight(THEM);
             Draw();
-            break;
+            goto stopall;
           }
         }
         break;
       }
     }
-    if(ib == -1) {      /* 'e' */
-      if(dim == 1) {
-        if(n >= 1)
-          add_trsfline(n, p, CTX.filename);
-      }
-      n = 0;
-      ZeroHighlight(THEM);
-      Draw();
-    }
-    if(ib == 0) {       /* 'q' */
-      n = 0;
-      ZeroHighlight(THEM);
-      Draw();
-      break;
-    }
   }
+
+stopall:
   Msg(STATUS3N, "Ready");
 }
 
@@ -3607,67 +3756,13 @@ void con_geometry_define_parameter_cb(CALLBACK_ARGS)
 
 void con_geometry_define_point_cb(CALLBACK_ARGS)
 {
-  strcpy(x_text, (char *)WID->context_geometry_input[2]->value());
-  strcpy(y_text, WID->context_geometry_input[3]->value());
-  strcpy(z_text, WID->context_geometry_input[4]->value());
-  strcpy(l_text, WID->context_geometry_input[5]->value());
-  add_point(CTX.filename);
+  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());
   ZeroHighlight(THEM);
   CalculateMinMax(THEM->Points, NULL);
   Draw();
 }
 
-void con_geometry_define_translation_cb(CALLBACK_ARGS)
-{
-  strcpy(tx_text, WID->context_geometry_input[6]->value());
-  strcpy(ty_text, WID->context_geometry_input[7]->value());
-  strcpy(tz_text, WID->context_geometry_input[8]->value());
-}
-
-void con_geometry_define_rotation_cb(CALLBACK_ARGS)
-{
-  strcpy(px_text, WID->context_geometry_input[9]->value());
-  strcpy(py_text, WID->context_geometry_input[10]->value());
-  strcpy(pz_text, WID->context_geometry_input[11]->value());
-  strcpy(ax_text, WID->context_geometry_input[12]->value());
-  strcpy(ay_text, WID->context_geometry_input[13]->value());
-  strcpy(az_text, WID->context_geometry_input[14]->value());
-  strcpy(angle_text, WID->context_geometry_input[15]->value());
-}
-
-void con_geometry_define_scale_cb(CALLBACK_ARGS)
-{
-  strcpy(dx_text, WID->context_geometry_input[16]->value());
-  strcpy(dy_text, WID->context_geometry_input[17]->value());
-  strcpy(dz_text, WID->context_geometry_input[18]->value());
-  strcpy(df_text, WID->context_geometry_input[19]->value());
-}
-
-void con_geometry_define_symmetry_cb(CALLBACK_ARGS)
-{
-  strcpy(sa_text, WID->context_geometry_input[20]->value());
-  strcpy(sb_text, WID->context_geometry_input[21]->value());
-  strcpy(sc_text, WID->context_geometry_input[22]->value());
-  strcpy(sd_text, WID->context_geometry_input[23]->value());
-}
-
-
-// Contextual windows for mesh
-
-void con_mesh_define_length_cb(CALLBACK_ARGS)
-{
-  strcpy(char_length_text, WID->context_mesh_input[0]->value());
-}
-
-void con_mesh_define_transfinite_line_cb(CALLBACK_ARGS)
-{
-  strcpy(trsf_pts_text, WID->context_mesh_input[1]->value());
-  strcpy(trsf_type_text,
-         (!WID->context_mesh_choice[0]->value())? "Progression" : "Bump");
-  strcpy(trsf_typearg_text, WID->context_mesh_input[2]->value());
-}
-
-void con_mesh_define_transfinite_volume_cb(CALLBACK_ARGS)
-{
-  strcpy(trsf_vol_text, WID->context_mesh_input[3]->value());
-}
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 983c8a1b43b1ed4f5b63fb869c82e3f4c32abea0..b1a63dae8200b2f9ec9e629bdfb654051b9eb744 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -239,10 +239,6 @@ void geometry_reload_cb(CALLBACK_ARGS) ;
 
 void con_geometry_define_parameter_cb(CALLBACK_ARGS) ;
 void con_geometry_define_point_cb(CALLBACK_ARGS) ;
-void con_geometry_define_translation_cb(CALLBACK_ARGS) ;
-void con_geometry_define_rotation_cb(CALLBACK_ARGS) ;
-void con_geometry_define_scale_cb(CALLBACK_ARGS) ;
-void con_geometry_define_symmetry_cb(CALLBACK_ARGS) ;
 
 // Dynamic Mesh Menus
 
@@ -260,10 +256,6 @@ void mesh_define_transfinite_line_cb(CALLBACK_ARGS) ;
 void mesh_define_transfinite_surface_cb(CALLBACK_ARGS) ;
 void mesh_define_transfinite_volume_cb(CALLBACK_ARGS) ; 
 
-void con_mesh_define_length_cb(CALLBACK_ARGS) ;
-void con_mesh_define_transfinite_line_cb(CALLBACK_ARGS) ;
-void con_mesh_define_transfinite_volume_cb(CALLBACK_ARGS) ;
-
 // Dynamic Solver Menus
 
 void solver_cb(CALLBACK_ARGS);
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index d3dac58fca32e4e1f27ebad9c017fb95f250d413..76f27b6c69e2d035f27b042a02e9dfea6e9eeb19 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.299 2004-05-17 18:04:53 geuzaine Exp $
+// $Id: GUI.cpp,v 1.300 2004-05-18 04:54:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -482,6 +482,10 @@ int GUI::global_shortcuts(int event)
     end_selection = 1;
     return 0;   // trick: do as if we didn't use it
   }
+  else if(Fl::test_shortcut('u')) {
+    undo_selection = 1;
+    return 0;   // trick: do as if we didn't use it
+  }
   else if(Fl::test_shortcut('q')) {
     quit_selection = 1;
     return 0;   // trick: do as if we didn't use it
@@ -3160,7 +3164,9 @@ void GUI::create_geometry_context_window(int num)
     {
       g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Parameter");
       context_geometry_input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Name");
+      context_geometry_input[0]->value("lc");
       context_geometry_input[1] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Value");
+      context_geometry_input[1]->value("1.0");
       for(i = 0; i < 2; i++) {
         context_geometry_input[i]->align(FL_ALIGN_RIGHT);
       }
@@ -3174,9 +3180,13 @@ void GUI::create_geometry_context_window(int num)
     {
       g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Point");
       context_geometry_input[2] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate");
+      context_geometry_input[2]->value("0.0");
       context_geometry_input[3] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate");
+      context_geometry_input[3]->value("0.0");
       context_geometry_input[4] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate");
+      context_geometry_input[4]->value("0.0");
       context_geometry_input[5] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Characteristic length");
+      context_geometry_input[5]->value("1.0");
       for(i = 2; i < 6; i++) {
         context_geometry_input[i]->align(FL_ALIGN_RIGHT);
       }
@@ -3190,66 +3200,68 @@ void GUI::create_geometry_context_window(int num)
     {
       g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Translation");
       context_geometry_input[6] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component");
+      context_geometry_input[6]->value("1.0");
       context_geometry_input[7] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component");
+      context_geometry_input[7]->value("0.0");
       context_geometry_input[8] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component");
+      context_geometry_input[8]->value("0.0");
       for(i = 6; i < 9; i++) {
         context_geometry_input[i]->align(FL_ALIGN_RIGHT);
       }
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Set");
-        o->callback(con_geometry_define_translation_cb);
-      }
       g[2]->end();
     }
     // 3: Rotation
     {
       g[3] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Rotation");
       context_geometry_input[9] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X coordinate of an axis point");
+      context_geometry_input[9]->value("0.0");
       context_geometry_input[10] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y coordinate of an axis point");
+      context_geometry_input[10]->value("0.0");
       context_geometry_input[11] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z coordinate of an axis point");
+      context_geometry_input[11]->value("0.0");
       context_geometry_input[12] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "X component of direction");
+      context_geometry_input[12]->value("0.0");
       context_geometry_input[13] = new Fl_Input(2 * WB, 2 * WB + 5 * BH, IW, BH, "Y component of direction");
+      context_geometry_input[13]->value("1.0");
       context_geometry_input[14] = new Fl_Input(2 * WB, 2 * WB + 6 * BH, IW, BH, "Z component of direction");
+      context_geometry_input[14]->value("0.0");
       context_geometry_input[15] = new Fl_Input(2 * WB, 2 * WB + 7 * BH, IW, BH, "Angle in radians");
+      context_geometry_input[15]->value("Pi/4");
       for(i = 9; i < 16; i++) {
         context_geometry_input[i]->align(FL_ALIGN_RIGHT);
       }
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Set");
-        o->callback(con_geometry_define_rotation_cb);
-      }
       g[3]->end();
     }
     // 4: Scale
     {
       g[4] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Scale");
       context_geometry_input[16] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "X component of direction");
+      context_geometry_input[16]->value("1.0");
       context_geometry_input[17] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "Y component of direction");
+      context_geometry_input[17]->value("0.0");
       context_geometry_input[18] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Z component of direction");
+      context_geometry_input[18]->value("0.0");
       context_geometry_input[19] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "Factor");
+      context_geometry_input[19]->value("2.0");
       for(i = 16; i < 20; i++) {
         context_geometry_input[i]->align(FL_ALIGN_RIGHT);
       }
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Set");
-        o->callback(con_geometry_define_scale_cb);
-      }
       g[4]->end();
     }
     // 5: Symmetry
     {
       g[5] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Symmetry");
       context_geometry_input[20] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "1st plane equation coefficient");
+      context_geometry_input[20]->value("1.0");
       context_geometry_input[21] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH, "2nd plane equation coefficient");
+      context_geometry_input[21]->value("0.0");
       context_geometry_input[22] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "3rd plane equation coefficient");
+      context_geometry_input[22]->value("0.0");
       context_geometry_input[23] = new Fl_Input(2 * WB, 2 * WB + 4 * BH, IW, BH, "4th plane equation coefficient");
+      context_geometry_input[23]->value("1.0");
       for(i = 20; i < 24; i++) {
         context_geometry_input[i]->align(FL_ALIGN_RIGHT);
       }
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 7 * BH, BB, BH, "Set");
-        o->callback(con_geometry_define_symmetry_cb);
-      }
       g[5]->end();
     }
     o->end();
@@ -3290,18 +3302,17 @@ void GUI::create_mesh_context_window(int num)
     {
       g[0] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Characteristic length");
       context_mesh_input[0] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Value");
+      context_mesh_input[0]->value("1.0");
       context_mesh_input[0]->align(FL_ALIGN_RIGHT);
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 3 * BH, BB, BH, "Set");
-        o->callback(con_mesh_define_length_cb);
-      }
       g[0]->end();
     }
     // 1: Transfinite line
     {
       g[1] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Transfinite line");
       context_mesh_input[1] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Number of points");
-      context_mesh_input[2] = new Fl_Input(2 * WB, 2 * WB + 2 * BH, IW, BH);
+      context_mesh_input[1]->value("10");
+      context_mesh_input[2] = new Fl_Input(2 * WB, 2 * WB + 3 * BH, IW, BH, "Parameter");
+      context_mesh_input[2]->value("1.0");
       for(i = 1; i < 3; i++) {
         context_mesh_input[i]->align(FL_ALIGN_RIGHT);
       }
@@ -3310,23 +3321,17 @@ void GUI::create_mesh_context_window(int num)
         {"Bump", 0, 0, 0},
         {0}
       };
-      context_mesh_choice[0] = new Fl_Choice(2 * WB + IW, 2 * WB + 2 * BH, IW, BH);
+      context_mesh_choice[0] = new Fl_Choice(2 * WB, 2 * WB + 2 * BH, IW, BH, "Type");
       context_mesh_choice[0]->menu(menu_trsf_mesh);
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 3 * BH, BB, BH, "Set");
-        o->callback(con_mesh_define_transfinite_line_cb);
-      }
+      context_mesh_choice[0]->align(FL_ALIGN_RIGHT);
       g[1]->end();
     }
     // 2: Transfinite volume
     {
       g[2] = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Transfinite volume");
       context_mesh_input[3] = new Fl_Input(2 * WB, 2 * WB + 1 * BH, IW, BH, "Volume number");
+      context_mesh_input[3]->value("1");
       context_mesh_input[3]->align(FL_ALIGN_RIGHT);
-      {
-        Fl_Return_Button *o = new Fl_Return_Button(width - BB - 2 * WB, 2 * WB + 3 * BH, BB, BH, "Set");
-        o->callback(con_mesh_define_transfinite_volume_cb);
-      }
       g[2]->end();
     }
     o->end();
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 65cc75c19034fb3b58e7123768571f983a52bf3c..b738faed7b2fb7edee574e8e246418d989dbfbd5 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -280,7 +280,7 @@ public:
   int  arrow_shortcuts();
   void reset_visibility();
   void reset_option_browser();
-  int  selection, try_selection, quit_selection, end_selection;
+  int  selection, try_selection, quit_selection, end_selection, undo_selection;
 
 };
 
diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp
index a9048c528cd518820ce510d9052945a2a75ef6c1..b44a6a98e1d8e69f532fd564dc0e24cbff4a2637 100644
--- a/Fltk/Opengl.cpp
+++ b/Fltk/Opengl.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl.cpp,v 1.38 2004-05-17 18:04:54 geuzaine Exp $
+// $Id: Opengl.cpp,v 1.39 2004-05-18 04:54:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -120,7 +120,7 @@ int check_type(int type, Vertex * v, Curve * c, Surface * s)
 	  (type == ENT_SURFACE && s));
 }
 
-int SelectEntity(int type, Vertex ** v, Curve ** c, Surface ** s)
+char SelectEntity(int type, Vertex ** v, Curve ** c, Surface ** s)
 {
   int hits;
   GLuint ii[SELECTION_BUFFER_SIZE], jj[SELECTION_BUFFER_SIZE];
@@ -129,6 +129,7 @@ int SelectEntity(int type, Vertex ** v, Curve ** c, Surface ** s)
   WID->try_selection = 0;
   WID->quit_selection = 0;
   WID->end_selection = 0;
+  WID->undo_selection = 0;
 
   while(1) {
     *v = NULL;
@@ -139,12 +140,16 @@ int SelectEntity(int type, Vertex ** v, Curve ** c, Surface ** s)
     if(WID->quit_selection) {
       WID->quit_selection = 0;
       WID->selection = 0;
-      return 0;
+      return 'q';
     }
     if(WID->end_selection) {
       WID->end_selection = 0;
       WID->selection = 0;
-      return -1;
+      return 'e';
+    }
+    if(WID->undo_selection) {
+      WID->undo_selection = 0;
+      return 'u';
     }
     if(WID->try_selection) {
       WID->try_selection = 0;
@@ -153,7 +158,7 @@ int SelectEntity(int type, Vertex ** v, Curve ** c, Surface ** s)
       if(check_type(type, *v, *c, *s)) {
         HighlightEntity(*v, *c, *s, 1);
         WID->selection = 0;
-        return 1;
+        return 'l';
       }
     }
   }
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 2dc0c61ff800b77a89cceec4f0816e75e3f35ef4..caabd2c5f1777dd2b2abef2f22af7a8de7b33725 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -1,4 +1,4 @@
-// $Id: Geo.cpp,v 1.39 2004-02-28 00:48:49 geuzaine Exp $
+// $Id: Geo.cpp,v 1.40 2004-05-18 04:54:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -42,22 +42,6 @@ int snprintf(char *str, size_t size, const char* fmt, ...){
 }
 #endif
 
-// This is truly horrible :-)
-
-char x_text[100] = "0.0", y_text[100] = "0.0", z_text[100] = "0.0";
-char l_text[100] = "1.0";
-char tx_text[100] = "0.0", ty_text[100] = "0.0", tz_text[100] = "0.0";
-char attrx_text[100] = "1.0", attry_text[100] = "1.0", attrz_text[100] = "1.0";
-char attrdec_text[100] = "2.0";
-char px_text[100] = "0.0", py_text[100] = "0.0", pz_text[100] = "0.0";
-char angle_text[100] = "3.14159/2";
-char ax_text[100] = "0.0", ay_text[100] = "0.0", az_text[100] = "1.0";
-char dx_text[100] = "0.0", dy_text[100] = "0.0", dz_text[100] = "0.0", df_text[100] = "1.0";
-char sa_text[100] = "0.0", sb_text[100] = "0.0", sc_text[100] = "0.0", sd_text[100] = "0.0";
-char trsf_pts_text[100] = "2", trsf_type_text[100] = "Progression", trsf_typearg_text[100] = "1.";
-char trsf_vol_text[100] = "1";
-char char_length_text[100] = "1.";
-
 double evaluate_scalarfunction(char *var, double val, char *funct)
 {
   FILE *tempf;
@@ -119,7 +103,7 @@ void delet(int p1, char *fich, char *what)
 {
   char text[BUFFSIZE];
 
-  snprintf(text, BUFFSIZE, "Delete {\n %s{%d};\n}", what, p1);
+  snprintf(text, BUFFSIZE, "Delete {\n  %s{%d};\n}", what, p1);
   add_infile(text, fich);
 }
 
@@ -159,7 +143,7 @@ void add_ellipticsurf(int N, int *l, char *fich)
   add_infile(text, fich);
 }
 
-void add_charlength(int N, int *l, char *fich)
+void add_charlength(int N, int *l, char *fich, char *lc)
 {
   char text[BUFFSIZE];
   char text2[BUFFSIZE];
@@ -172,7 +156,7 @@ void add_charlength(int N, int *l, char *fich)
       snprintf(text2, BUFFSIZE, ",%d", l[i]);
     strncat(text, text2, BUFFSIZE-strlen(text));
   }
-  snprintf(text2, BUFFSIZE, "} = %s;", char_length_text);
+  snprintf(text2, BUFFSIZE, "} = %s;", lc);
   strncat(text, text2, BUFFSIZE-strlen(text));
   add_infile(text, fich);
 }
@@ -196,7 +180,7 @@ void add_recosurf(int N, int *l, char *fich)
 }
 
 
-void add_trsfline(int N, int *l, char *fich)
+void add_trsfline(int N, int *l, char *fich, char *type, char *typearg, char *pts)
 {
   char text[BUFFSIZE];
   char text2[BUFFSIZE];
@@ -209,11 +193,10 @@ void add_trsfline(int N, int *l, char *fich)
       snprintf(text2, BUFFSIZE, ",%d", l[i]);
     strncat(text, text2, BUFFSIZE-strlen(text));
   }
-  if(strlen(trsf_typearg_text))
-    snprintf(text2, BUFFSIZE, "} = %s Using %s %s;", trsf_pts_text,
-             trsf_type_text, trsf_typearg_text);
+  if(strlen(typearg))
+    snprintf(text2, BUFFSIZE, "} = %s Using %s %s;", pts, type, typearg);
   else
-    snprintf(text2, BUFFSIZE, "} = %s;", trsf_pts_text);
+    snprintf(text2, BUFFSIZE, "} = %s;", pts);
   strncat(text, text2, BUFFSIZE-strlen(text));
   add_infile(text, fich);
 }
@@ -226,31 +209,25 @@ void add_param(char *par, char *value, char *fich)
   add_infile(text, fich);
 }
 
-void add_point(char *fich)
+void add_point(char *fich, char *x, char *y, char *z, char *lc)
 {
   char text[BUFFSIZE];
-  int ip;
-
-  ip = NEWPOINT();
-  snprintf(text, BUFFSIZE, "Point(%d) = {%s,%s,%s,%s};", ip, x_text, y_text,
-           z_text, l_text);
+  int ip = NEWPOINT();
+  snprintf(text, BUFFSIZE, "Point(%d) = {%s,%s,%s,%s};", ip, x, y, z, lc);
   add_infile(text, fich);
 }
 
-void add_attractor(char *fich, int ip, int typ)
+void add_attractor(char *fich, int ip, int typ, char *ax, char *ay, char *ad)
 {
   char text[BUFFSIZE];
   if(typ == 0) {
-    snprintf(text, BUFFSIZE, "Attractor Point {%d} = {%s,%s,%s} = ;",
-             ip, attrx_text, attry_text, attrdec_text);
+    snprintf(text, BUFFSIZE, "Attractor Point {%d} = {%s,%s,%s} = ;", ip, ax, ay, ad);
   }
   else if(typ == 1) {
-    snprintf(text, BUFFSIZE, "Attractor Line {%d} = {%s,%s,%s};",
-             ip, attrx_text, attry_text, attrdec_text);
+    snprintf(text, BUFFSIZE, "Attractor Line {%d} = {%s,%s,%s};", ip, ax, ay, ad);
   }
   else if(typ == 2) {
-    snprintf(text, BUFFSIZE, "Attractor Surface {%d} = {%s,%s,%s};",
-             ip, attrx_text, attry_text, attrdec_text);
+    snprintf(text, BUFFSIZE, "Attractor Surface {%d} = {%s,%s,%s};", ip, ax, ay, ad);
   }
   add_infile(text, fich);
 }
@@ -459,12 +436,12 @@ void add_multvol(List_T * list, char *fich)
   add_infile(text, fich);
 }
 
-void add_trsfvol(int N, int *l, char *fich)
+void add_trsfvol(int N, int *l, char *fich, char *vol)
 {
   char text[BUFFSIZE], text2[BUFFSIZE];
   int i;
 
-  snprintf(text, BUFFSIZE, "Transfinite Volume{%s} = {", trsf_vol_text);
+  snprintf(text, BUFFSIZE, "Transfinite Volume{%s} = {", vol);
   for(i = 0; i < N; i++) {
     if(i == 0)
       snprintf(text2, BUFFSIZE, "%d", l[i]);
@@ -510,81 +487,76 @@ void add_physical(List_T * list, char *fich, int type, int *num)
   add_infile(text, fich);
 }
 
-void translate(int add, int s, char *fich, char *what)
+void translate(int add, int s, char *fich, char *what, char *tx, char *ty, char *tz)
 {
   char text[BUFFSIZE];
 
   if(add)
     snprintf(text, BUFFSIZE,
-             "Translate {%s,%s,%s} {\n  Duplicata { %s{%d}; }\n}", tx_text,
-             ty_text, tz_text, what, s);
+             "Translate {%s,%s,%s} {\n  Duplicata { %s{%d}; }\n}", tx, ty, tz, what, s);
   else
-    snprintf(text, BUFFSIZE, "Translate {%s,%s,%s} {\n  %s{%d};\n}",
-             tx_text, ty_text, tz_text, what, s);
+    snprintf(text, BUFFSIZE, "Translate {%s,%s,%s} {\n  %s{%d};\n}", tx, ty, tz, what, s);
   add_infile(text, fich);
 }
 
-void rotate(int add, int s, char *fich, char *quoi)
+void rotate(int add, int s, char *fich, char *what, char *ax, char *ay, char *az,
+	    char *px, char *py, char *pz, char *angle)
 {
   char text[BUFFSIZE];
 
   if(add)
     snprintf(text, BUFFSIZE,
              "Rotate { {%s,%s,%s},{%s,%s,%s},%s } {\n  Duplicata { %s{%d}; }\n}",
-             ax_text, ay_text, az_text, px_text, py_text, pz_text, angle_text,
-             quoi, s);
+             ax, ay, az, px, py, pz, angle, what, s);
   else
     snprintf(text, BUFFSIZE,
-             "Rotate { {%s,%s,%s},{%s,%s,%s},%s } {\n   %s{%d};\n  }",
-             ax_text, ay_text, az_text, px_text, py_text, pz_text, angle_text,
-             quoi, s);
+             "Rotate { {%s,%s,%s},{%s,%s,%s},%s } {\n  %s{%d};\n}",
+             ax, ay, az, px, py, pz, angle, what, s);
   add_infile(text, fich);
 }
 
-void dilate(int add, int s, char *fich, char *quoi)
+void dilate(int add, int s, char *fich, char *what, char *dx, char *dy, char *dz, char *df)
 {
   char text[BUFFSIZE];
 
   if(add)
     snprintf(text, BUFFSIZE,
              "Dilate { {%s,%s,%s},%s } {\n  Duplicata { %s{%d}; }\n}",
-             dx_text, dy_text, dz_text, df_text, quoi, s);
+             dx, dy, dz, df, what, s);
   else
-    snprintf(text, BUFFSIZE, "Dilate { {%s,%s,%s},%s } {\n   %s{%d};\n  }",
-             dx_text, dy_text, dz_text, df_text, quoi, s);
+    snprintf(text, BUFFSIZE, "Dilate { {%s,%s,%s},%s } {\n  %s{%d};\n}",
+             dx, dy, dz, df, what, s);
   add_infile(text, fich);
 }
 
-void symmetry(int add, int s, char *fich, char *quoi)
+void symmetry(int add, int s, char *fich, char *what, char *sa, char *sb, char *sc, char *sd)
 {
   char text[BUFFSIZE];
 
   if(add)
     snprintf(text, BUFFSIZE,
              "Symmetry { %s,%s,%s,%s } {\n  Duplicata { %s{%d}; }\n}",
-             sa_text, sb_text, sc_text, sd_text, quoi, s);
+             sa, sb, sc, sd, what, s);
   else
-    snprintf(text, BUFFSIZE, "Symmetry { %s,%s,%s,%s } {\n   %s{%d};\n  }",
-             sa_text, sb_text, sc_text, sd_text, quoi, s);
+    snprintf(text, BUFFSIZE, "Symmetry { %s,%s,%s,%s } {\n  %s{%d};\n}",
+             sa, sb, sc, sd, what, s);
   add_infile(text, fich);
-
 }
 
-void extrude(int s, char *fich, char *what)
+void extrude(int s, char *fich, char *what, char *tx, char *ty, char *tz)
 {
   char text[BUFFSIZE];
 
-  snprintf(text, BUFFSIZE, "Extrude %s {%d, {%s,%s,%s}};", what, s, tx_text,
-           ty_text, tz_text);
+  snprintf(text, BUFFSIZE, "Extrude %s {%d, {%s,%s,%s}};", what, s, tx, ty, tz);
   add_infile(text, fich);
 }
 
-void protude(int s, char *fich, char *what)
+void protude(int s, char *fich, char *what, char *ax, char *ay, char *az,
+	     char *px, char *py, char *pz, char *angle)
 {
   char text[BUFFSIZE];
 
   snprintf(text, BUFFSIZE, "Extrude %s {%d, {%s,%s,%s}, {%s,%s,%s}, %s};",
-           what, s, ax_text, ay_text, az_text, px_text, py_text, pz_text,
-           angle_text);
+           what, s, ax, ay, az, px, py, pz, angle);
   add_infile(text, fich);
 }
diff --git a/Geo/Geo.h b/Geo/Geo.h
index ce5bf85ee33c6cde708a2269cdbbfca0451a12dd..dd3c81e04dcf5dcfb2b69ec3b5c101b4efc4d478 100644
--- a/Geo/Geo.h
+++ b/Geo/Geo.h
@@ -92,34 +92,18 @@ typedef struct {
   } obj;
 } Shape;
 
-// static strings for parser interaction
-extern char x_text[100], y_text[100], z_text[100];
-extern char l_text[100];
-extern char tx_text[100], ty_text[100], tz_text[100];
-extern char attrx_text[100], attry_text[100], attrz_text[100];
-extern char attrdec_text[100];
-extern char px_text[100], py_text[100], pz_text[100];
-extern char angle_text[100] ;
-extern char ax_text[100], ay_text[100], az_text[100];
-extern char dx_text[100], dy_text[100], dz_text[100], df_text[100];
-extern char sa_text[100], sb_text[100], sc_text[100], sd_text[100];
-extern char nb_pts[100], mode_value[100];
-extern char trsf_pts_text[100], trsf_type_text[100], trsf_typearg_text[100];
-extern char trsf_vol_text[100];
-extern char char_length_text[100];
-
 double evaluate_scalarfunction (char *var, double val, char *funct);
 
 void delet(int p1, char *fich, char *what);
 void add_infile(char *text, char *fich);
-void add_trsfsurf (int N, int *l, char *fich);
-void add_trsfvol (int N, int *l, char *fich);
-void add_ellipticsurf (int N, int *l, char *fich);
-void add_charlength (int N, int *l, char *fich);
-void add_recosurf (int N, int *l, char *fich);
-void add_trsfline (int N, int *l, char *fich);
-void add_param (char *par, char *value, char *fich);
-void add_point(char *fich);
+void add_trsfsurf(int N, int *l, char *fich);
+void add_trsfvol(int N, int *l, char *fich, char *vol);
+void add_ellipticsurf(int N, int *l, char *fich);
+void add_charlength(int N, int *l, char *fich, char *lc);
+void add_recosurf(int N, int *l, char *fich);
+void add_trsfline(int N, int *l, char *fich, char *type, char *typearg, char *pts);
+void add_param(char *par, char *value, char *fich);
+void add_point(char *fich, char *x, char *y, char *z, char *lc);
 void add_attractor(char *fich, int ip, int typ);
 void add_line(int p1, int p2, char *fich);
 void add_circ(int p1, int p2, int p3, char *fich);
@@ -133,11 +117,13 @@ void add_surf(List_T *list, char *fich, int support, int typ);
 void add_vol(List_T *list, char *fich, int *numvol);
 void add_multvol(List_T *list, char *fich);
 void add_physical(List_T *list, char *fich, int type, int *num);
-void translate(int add, int s, char *fich, char*what);
-void rotate(int add, int s, char *fich, char *what);
-void dilate(int add, int s, char *fich, char *what);
-void symmetry(int add, int s, char *fich, char *what);
-void extrude(int s, char *fich, char *what);
-void protude(int s, char *fich, char *what);
+void translate(int add, int s, char *fich, char *what, char *tx, char *ty, char *tz);
+void rotate(int add, int s, char *fich, char *what, char *ax, char *ay, char *az,
+	    char *px, char *py, char *pz, char *angle);
+void dilate(int add, int s, char *fich, char *what, char *dx, char *dy, char *dz, char *df);
+void symmetry(int add, int s, char *fich, char *what, char *sa, char *sb, char *sc, char *sd);
+void extrude(int s, char *fich, char *what, char *tx, char *ty, char *tz);
+void protude(int s, char *fich, char *what, char *ax, char *ay, char *az,
+	     char *px, char *py, char *pz, char *angle);
 
 #endif
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 2ab2338daf6bb5c146d83bf61050b32790c96680..21de9ddd3b347fd7e8a0d89bd31964d830072d30 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -47,10 +47,11 @@ void PaletteContinuousLinear(Post_View * v, double min, double max, double val);
 void PaletteDiscrete(Post_View * View, int nbi, int i);
 void ColorSwitch(int i);
 
-int  SelectEntity(int type, Vertex **v, Curve **c, Surface **s);
-void ZeroHighlight(Mesh *m);
+char SelectEntity(int type, Vertex **v, Curve **c, Surface **s);
 void HighlightEntity(Vertex *v,Curve *c, Surface *s, int permanent);
 void HighlightEntityNum(int v, int c, int s, int permanant);
+void ZeroHighlight(Mesh *m);
+void ZeroHighlightEntityNum(int v, int c, int s);
 
 void Draw3d(void);
 void Draw2d(void);
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 9beb232d49fdc99b556c14cf046971c47144f2ac..103dbb2d4612b85bb900adef0285fec0037a6666 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.56 2004-05-17 18:46:51 geuzaine Exp $
+// $Id: Geom.cpp,v 1.57 2004-05-18 04:54:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -309,7 +309,10 @@ void Draw_Plane_Surface(Surface * s)
   static List_T *points;
   static int deb = 1;
 
-  if(!s->Orientations) {
+  if(!s->Orientations)
+    s->Orientations = List_Create(20, 2, sizeof(Vertex));
+
+  if(!List_Nbr(s->Orientations)) {
 
     s->Orientations = List_Create(20, 2, sizeof(Vertex));
 
@@ -698,21 +701,21 @@ void HighlightEntityNum(int v, int c, int s, int permanent)
   }
 }
 
-void ZeroPoint(void *a, void *b)
+void ZeroHighlightPoint(void *a, void *b)
 {
   Vertex *v;
   v = *(Vertex **) a;
   v->Frozen = 0;
 }
 
-void ZeroCurve(void *a, void *b)
+void ZeroHighlightCurve(void *a, void *b)
 {
   Curve *c;
   c = *(Curve **) a;
   c->ipar[3] = 0;
 }
 
-void ZeroSurface(void *a, void *b)
+void ZeroHighlightSurface(void *a, void *b)
 {
   Surface *s;
   s = *(Surface **) a;
@@ -721,7 +724,26 @@ void ZeroSurface(void *a, void *b)
 
 void ZeroHighlight(Mesh * m)
 {
-  Tree_Action(m->Points, ZeroPoint);
-  Tree_Action(m->Curves, ZeroCurve);
-  Tree_Action(m->Surfaces, ZeroSurface);
+  Tree_Action(m->Points, ZeroHighlightPoint);
+  Tree_Action(m->Curves, ZeroHighlightCurve);
+  Tree_Action(m->Surfaces, ZeroHighlightSurface);
+}
+
+void ZeroHighlightEntityNum(int v, int c, int s)
+{
+  if(v) {
+    Vertex *pv = FindPoint(v, THEM);
+    if(pv)
+      ZeroHighlightPoint(&pv, NULL);
+  }
+  if(c) {
+    Curve *pc = FindCurve(c, THEM);
+    if(pc)
+      ZeroHighlightCurve(&pc, NULL);
+  }
+  if(s) {
+    Surface *ps = FindSurface(s, THEM);
+    if(ps)
+      ZeroHighlightSurface(&ps, NULL);
+  }
 }
diff --git a/Mesh/Create.cpp b/Mesh/Create.cpp
index 1dd19b89bd6bac4c096e89096e8355b5e552765a..ce1fa935e23821de96ed3a7890d93804d9b739bb 100644
--- a/Mesh/Create.cpp
+++ b/Mesh/Create.cpp
@@ -1,4 +1,4 @@
-// $Id: Create.cpp,v 1.49 2004-05-12 22:51:07 geuzaine Exp $
+// $Id: Create.cpp,v 1.50 2004-05-18 04:54:50 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -511,6 +511,9 @@ void End_Surface(Surface * s)
 {
   int i;
   Vertex *v;
+  
+  if(s->Orientations) 
+    List_Reset(s->Orientations);
 
   if(!s->Control_Points || !List_Nbr(s->Control_Points))
     return;
diff --git a/TODO b/TODO
index e091e2ca22dbeeb9aefb49a64385be6ac2688d7a..288dd9a8f746d8abcb30f36a05ff5236fcce9062 100644
--- a/TODO
+++ b/TODO
@@ -1,9 +1,4 @@
-$Id: TODO,v 1.46 2004-05-14 16:47:30 geuzaine Exp $
-
-add a way to undo the geometry contour selections in the
-GUI... (un-click)
-
-********************************************************************
+$Id: TODO,v 1.47 2004-05-18 04:54:49 geuzaine Exp $
 
 add ternary operator and <,>,<=,>=,== tests in MathEval
 
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 63abcc306d26ef7bc46859527363e5a22a7c201a..bc7780b739949000b5b1d5540b0f9263145e842b 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,11 +1,12 @@
-$Id: VERSIONS,v 1.206 2004-05-15 08:37:18 geuzaine Exp $
+$Id: VERSIONS,v 1.207 2004-05-18 04:54:51 geuzaine Exp $
 
 New since 1.52: various background mesh fixes and enhancements; new
 Plugin(Evaluate) to evaluate arbitrary expressions on post-processing
 views; generalized Plugin(Extract) to handle any combination of
 components; generalized "Coherence" to handle transfinite
 surface/volume attributes; plugin options can now be set in the option
-file (like all other options); many small cleanups;
+file (like all other options); added "undo" capability during geometry
+creation; many small cleanups;
 
 New in 1.52: new raster ("bitmap") PostScript/EPS/PDF output formats;
 new Plugin(Extract) to extract a given component from a