From d34791b9511a18f11cdbc9ce07fc84dd12d27614 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 18 May 2004 17:00:37 +0000
Subject: [PATCH] display the interactive messages in the graphic window
 (instead of the status bar)

---
 Common/Message.h      |   4 +-
 Fltk/Callbacks.cpp    | 112 +++++++++++++++++++++++++++++++++---------
 Fltk/GUI.cpp          |  57 ++++++++++++---------
 Fltk/GUI.h            |   3 ++
 Fltk/Message.cpp      |   6 ++-
 Fltk/Opengl.cpp       |  21 +++++++-
 Graphics/Draw.cpp     |   3 +-
 Graphics/Draw.h       |   1 +
 doc/texinfo/gmsh.texi |  11 ++---
 9 files changed, 162 insertions(+), 56 deletions(-)

diff --git a/Common/Message.h b/Common/Message.h
index b120fa8bce..3c799c9cf9 100644
--- a/Common/Message.h
+++ b/Common/Message.h
@@ -55,8 +55,10 @@
 #define STATUS2N      25  // Same as STATUS2, but not going into the log file
 #define STATUS3N      26  // Same as STATUS3, but not going into the log file
 
-#define DIRECT        30  // Direct message (no special formatting)
+#define ONSCREEN1     27  // Persistent on-screen message (line 1)
+#define ONSCREEN2     28  // Persistent on-screen message (line 2)
 
+#define DIRECT        30  // Direct message (no special formatting)
 #define SOLVER        31  // Solver message
 #define SOLVERR       32  // Solver errors and warnings
 
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 5d285fe617..e8c3101682 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.232 2004-05-18 04:54:50 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.233 2004-05-18 17:00:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -1009,7 +1009,9 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
     Draw();
   }
 
-  Msg(STATUS3N, "Select point ('q'=abort)");
+  Msg(STATUS3N, "Setting rotation center");
+  Msg(ONSCREEN1, "Select point");
+  Msg(ONSCREEN2, "[Press 'q' to abort]");
   char ib = SelectEntity(ENT_POINT, &v, &c, &s);
   if(ib == 'l') {
     // This would bypass the "Apply" button... Not necessarily bad,
@@ -1026,6 +1028,8 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
   ZeroHighlight(THEM);
   Draw();
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void general_options_ok_cb(CALLBACK_ARGS)
@@ -1772,9 +1776,12 @@ static void _new_multiline(int type)
     Draw();
   }
 
+  Msg(ONSCREEN1, "Select control points");
+  Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+
   n = 0;
   while(1) {
-    Msg(STATUS3N, "Select points ('e'=end, 'u'=undo, 'q'=abort)");
+    Msg(STATUS3N, "Creating curve");
     char ib = SelectEntity(ENT_POINT, &v, &c, &s);
     if(ib == 'l') {
       p[n++] = v->Num;
@@ -1813,7 +1820,10 @@ static void _new_multiline(int type)
       break;
     }
   }
+
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
@@ -1833,12 +1843,15 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
     Draw();
   }
 
+  Msg(ONSCREEN2, "[Press 'u' to undo last selection or 'q' to abort]");
+
   n = 0;
   while(1) {
+    Msg(STATUS3N, "Creating straight line");
     if(n == 0)
-      Msg(STATUS3N, "Select start point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select start point");
     if(n == 1)
-      Msg(STATUS3N, "Select end point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select end point");
     char ib = SelectEntity(ENT_POINT, &v, &c, &s);
     if(ib == 'l') {
       p[n++] = v->Num;
@@ -1862,7 +1875,10 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
       n = 0;
     }
   }
+
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void geometry_elementary_add_new_spline_cb(CALLBACK_ARGS)
@@ -1887,14 +1903,17 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
     Draw();
   }
 
+  Msg(ONSCREEN2, "[Press 'u' to undo last selection or 'q' to abort]");
+
   n = 0;
   while(1) {
+    Msg(STATUS3N, "Creating circle");
     if(n == 0)
-      Msg(STATUS3N, "Select start point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select start point");
     if(n == 1)
-      Msg(STATUS3N, "Select center point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select center point");
     if(n == 2)
-      Msg(STATUS3N, "Select end point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select end point");
     char ib = SelectEntity(ENT_POINT, &v, &c, &s);
     if(ib == 'l') {
       p[n++] = v->Num;
@@ -1918,7 +1937,10 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
       n = 0;
     }
   }
+
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
@@ -1933,16 +1955,19 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
     Draw();
   }
 
+  Msg(ONSCREEN2, "[Press 'u' to undo last selection or 'q' to abort]");
+
   n = 0;
   while(1) {
+    Msg(STATUS3N, "Creating ellipse");
     if(n == 0)
-      Msg(STATUS3N, "Select start point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select start point");
     if(n == 1)
-      Msg(STATUS3N, "Select center point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select center point");
     if(n == 2)
-      Msg(STATUS3N, "Select major axis point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select major axis point");
     if(n == 3)
-      Msg(STATUS3N, "Select end point ('u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select end point");
     char ib = SelectEntity(ENT_POINT, &v, &c, &s);
     if(ib == 'l') {
       p[n++] = v->Num;
@@ -1966,7 +1991,10 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
       n = 0;
     }
   }
+
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 static void _new_surface_volume(int mode)
@@ -2001,7 +2029,15 @@ static void _new_surface_volume(int mode)
     List_Reset(ListUnsorted);
 
     while(1) {
-      Msg(STATUS3N, "Select exterior boundary ('u'=undo, 'q'=abort)");
+      if(type == ENT_LINE){
+	Msg(STATUS3N, "Creating surface");
+	Msg(ONSCREEN1, "Select surface boundary");
+      }
+      else{
+	Msg(STATUS3N, "Creating volume");
+	Msg(ONSCREEN1, "Select volume boundary");
+      }
+      Msg(ONSCREEN2, "[Press 'u' to undo last selection or 'q' to abort]");
       char ib = SelectEntity(type, &v, &c, &s);
       if(ib == 'q') {
         ZeroHighlight(THEM);
@@ -2040,7 +2076,8 @@ static void _new_surface_volume(int mode)
 	  List_Reset(ListUnsorted);
 	  List_Add(List2, &num);
 	  while(1) {
-	    Msg(STATUS3N, "Select hole boundaries ('e'=end, 'u'=undo, 'q'=abort)");
+	    Msg(ONSCREEN1, "Select hole boundaries (if any)");
+	    Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
 	    ib = SelectEntity(type, &v, &c, &s);
 	    if(ib == 'q') {
 	      ZeroHighlight(THEM);
@@ -2106,6 +2143,8 @@ stopall:;
   List_Delete(List2);
   List_Delete(ListUnsorted);
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void geometry_elementary_add_new_planesurface_cb(CALLBACK_ARGS)
@@ -2156,8 +2195,11 @@ static void _transform_point_line_surface(int transfo, int mode, char *what)
     }
   }
 
+  Msg(ONSCREEN1, "Select %s", str);
+  Msg(ONSCREEN2, "[Press 'q' to abort]");
+
   while(1) {
-    Msg(STATUS3N, "Select %s ('q'=abort)", str);
+    Msg(STATUS3N, "Transforming %s", str);
     char ib = SelectEntity(type, &v, &c, &s);
     if(ib == 'q') {
       ZeroHighlight(THEM);
@@ -2232,7 +2274,10 @@ static void _transform_point_line_surface(int transfo, int mode, char *what)
       Draw();
     }
   }
+
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void geometry_elementary_add_translate_cb(CALLBACK_ARGS)
@@ -2535,9 +2580,12 @@ static void _add_physical(char *what)
     return;
   }
 
+  Msg(ONSCREEN1, "Select %s", str);
+  Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+
   List1 = List_Create(5, 5, sizeof(int));
   while(1) {
-    Msg(STATUS3N, "Select %s ('e'=end, 'u'=undo, 'q'=abort)", str);
+    Msg(STATUS3N, "Creating physical %s", str);
     char ib = SelectEntity(type, &v, &c, &s);
     if(ib == 'l') {
       switch (type) {
@@ -2578,6 +2626,8 @@ static void _add_physical(char *what)
   }
   List_Delete(List1);
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void geometry_physical_add_cb(CALLBACK_ARGS)
@@ -2676,8 +2726,11 @@ void mesh_define_length_cb(CALLBACK_ARGS)
 
   WID->create_mesh_context_window(0);
 
+  Msg(ONSCREEN1, "Select points");
+  Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+
   while(1) {
-    Msg(STATUS3N, "Select points ('e'=end, 'u'=undo, 'q'=qbort)");
+    Msg(STATUS3N, "Setting characteristic length");
     char ib = SelectEntity(ENT_POINT, &v, &c, &s);
     if(ib == 'l') {
       p[n++] = v->Num;
@@ -2703,6 +2756,8 @@ void mesh_define_length_cb(CALLBACK_ARGS)
     }
   }
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void mesh_define_recombine_cb(CALLBACK_ARGS)
@@ -2717,9 +2772,12 @@ void mesh_define_recombine_cb(CALLBACK_ARGS)
     Draw();
   }
 
+  Msg(ONSCREEN1, "Select surface");
+  Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
+
   n = 0;
   while(1) {
-    Msg(STATUS3N, "Select surface ('e'=end, 'u'=undo, 'q'=qbort)");
+    Msg(STATUS3N, "Selecting recombined surfaces");
     char ib = SelectEntity(ENT_SURFACE, &v, &c, &s);
     if(ib == 'l') {
       p[n++] = s->Num;
@@ -2745,6 +2803,8 @@ void mesh_define_recombine_cb(CALLBACK_ARGS)
     }
   }
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void mesh_define_transfinite_cb(CALLBACK_ARGS)
@@ -2788,13 +2848,16 @@ static void _add_transfinite(int dim)
 
   n = 0;
   while(1) {
+    Msg(STATUS3N, "Setting transfinite contraints");
     switch (dim) {
     case 1:
-      Msg(STATUS3N, "Select lines ('e'=end, 'u'=undo, 'q'=abort)");
+      Msg(ONSCREEN1, "Select lines");
+      Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
       ib = SelectEntity(ENT_LINE, &v, &c, &s);
       break;
     case 2:
-      Msg(STATUS3N, "Select surface ('q'=abort)");
+      Msg(ONSCREEN1, "Select surface");
+      Msg(ONSCREEN2, "[Press 'q' to abort]");
       ib = SelectEntity(ENT_SURFACE, &v, &c, &s);
       break;
     default:
@@ -2837,7 +2900,8 @@ static void _add_transfinite(int dim)
         p[n++] = s->Num; // fall-through
       case 3:
         while(1) {
-          Msg(STATUS3N, "Select points ('e'=end, 'u'=undo, 'q'=quit)");
+	  Msg(ONSCREEN1, "Select boundary points (in order)");
+	  Msg(ONSCREEN2, "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
           ib = SelectEntity(ENT_POINT, &v, &c, &s);
           if(ib == 'l') {
             p[n++] = v->Num;
@@ -2855,14 +2919,14 @@ static void _add_transfinite(int dim)
               if(n == 3 + 1 || n == 4 + 1)
                 add_trsfsurf(n, p, CTX.filename);
               else
-                Msg(STATUS2, "Wrong number of points for transfinite surface");
+                Msg(GERROR, "Wrong number of points for transfinite surface");
               break;
             case 3:
               if(n == 6 || n == 8)
                 add_trsfvol(n, p, CTX.filename, 
 			    (char*)WID->context_mesh_input[3]->value());
               else
-                Msg(STATUS2, "Wrong number of points for transfinite volume");
+                Msg(GERROR, "Wrong number of points for transfinite volume");
               break;
             }
             ZeroHighlight(THEM);
@@ -2883,6 +2947,8 @@ static void _add_transfinite(int dim)
 
 stopall:
   Msg(STATUS3N, "Ready");
+  Msg(ONSCREEN1, "");
+  Msg(ONSCREEN2, "");
 }
 
 void mesh_define_transfinite_line_cb(CALLBACK_ARGS)
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 76f27b6c69..46d454eccd 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.300 2004-05-18 04:54:50 geuzaine Exp $
+// $Id: GUI.cpp,v 1.301 2004-05-18 17:00:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -196,7 +196,7 @@ Context_Item menu_geometry[] = {
   { NULL }
 };  
     Context_Item menu_geometry_elementary[] = {
-      { "0Geometry Elementary", NULL } ,
+      { "0Geometry > Elementary", NULL } ,
       { "Add",       (Fl_Callback *)geometry_elementary_add_cb } ,
       { "Translate", (Fl_Callback *)geometry_elementary_translate_cb } ,
       { "Rotate",    (Fl_Callback *)geometry_elementary_rotate_cb } ,
@@ -207,7 +207,7 @@ Context_Item menu_geometry[] = {
       { NULL } 
     };  
         Context_Item menu_geometry_elementary_add[] = {
-	  { "0Geometry Elementary Add", NULL } ,
+	  { "0Geometry > Elementary > Add", NULL } ,
           { "New",       (Fl_Callback *)geometry_elementary_add_new_cb } ,
 	  { "Translate", (Fl_Callback *)geometry_elementary_add_translate_cb } ,
 	  { "Rotate",    (Fl_Callback *)geometry_elementary_add_rotate_cb } ,
@@ -216,7 +216,7 @@ Context_Item menu_geometry[] = {
 	  { NULL } 
 	};  
             Context_Item menu_geometry_elementary_add_new[] = {
-	      { "0Geometry Elementary Add New", NULL } ,
+	      { "0Geometry > Elementary > Add > New", NULL } ,
               { "Parameter",     (Fl_Callback *)geometry_elementary_add_new_parameter_cb } ,
 	      { "Point",         (Fl_Callback *)geometry_elementary_add_new_point_cb } ,
 	      { "Straight line", (Fl_Callback *)geometry_elementary_add_new_line_cb } ,
@@ -230,95 +230,95 @@ Context_Item menu_geometry[] = {
 	      { NULL } 
 	    };  
             Context_Item menu_geometry_elementary_add_translate[] = {
-	      { "0Geometry Elementary Add Translate", NULL } ,
+	      { "0Geometry > Elementary > Add > Translate", NULL } ,
               { "Point",   (Fl_Callback *)geometry_elementary_add_translate_point_cb } ,
 	      { "Line",    (Fl_Callback *)geometry_elementary_add_translate_line_cb } ,
 	      { "Surface", (Fl_Callback *)geometry_elementary_add_translate_surface_cb } ,
 	      { NULL } 
 	    };  
             Context_Item menu_geometry_elementary_add_rotate[] = {
-	      { "0Geometry Elementary Add Rotate", NULL } ,
+	      { "0Geometry > Elementary > Add > Rotate", NULL } ,
               { "Point",   (Fl_Callback *)geometry_elementary_add_rotate_point_cb } ,
 	      { "Line",    (Fl_Callback *)geometry_elementary_add_rotate_line_cb } ,
 	      { "Surface", (Fl_Callback *)geometry_elementary_add_rotate_surface_cb } ,
 	      { NULL } 
 	    };  
             Context_Item menu_geometry_elementary_add_scale[] = {
-	      { "0Geometry Elementary Add Scale", NULL } ,
+	      { "0Geometry > Elementary > Add > Scale", NULL } ,
 	      { "Point",   (Fl_Callback *)geometry_elementary_add_scale_point_cb } ,
 	      { "Line",    (Fl_Callback *)geometry_elementary_add_scale_line_cb } ,
 	      { "Surface", (Fl_Callback *)geometry_elementary_add_scale_surface_cb } ,
 	      { NULL } 
 	    };  
             Context_Item menu_geometry_elementary_add_symmetry[] = {
-	      { "0Geometry Elementary Add Symmetry", NULL } ,
+	      { "0Geometry > Elementary > Add > Symmetry", NULL } ,
 	      { "Point",   (Fl_Callback *)geometry_elementary_add_symmetry_point_cb } ,
 	      { "Line",    (Fl_Callback *)geometry_elementary_add_symmetry_line_cb } ,
 	      { "Surface", (Fl_Callback *)geometry_elementary_add_symmetry_surface_cb } ,
 	      { NULL } 
 	    };  
         Context_Item menu_geometry_elementary_translate[] = {
-	  { "0Geometry Elementary Translate", NULL } ,
+	  { "0Geometry > Elementary > Translate", NULL } ,
 	  { "Point",   (Fl_Callback *)geometry_elementary_translate_point_cb } ,
 	  { "Line",    (Fl_Callback *)geometry_elementary_translate_line_cb } ,
 	  { "Surface", (Fl_Callback *)geometry_elementary_translate_surface_cb } ,
 	  { NULL } 
 	};  
         Context_Item menu_geometry_elementary_rotate[] = {
-	  { "0Geometry Elementary Rotate", NULL } ,
+	  { "0Geometry > Elementary > Rotate", NULL } ,
 	  { "Point",   (Fl_Callback *)geometry_elementary_rotate_point_cb } ,
 	  { "Line",    (Fl_Callback *)geometry_elementary_rotate_line_cb } ,
 	  { "Surface", (Fl_Callback *)geometry_elementary_rotate_surface_cb } ,
 	  { NULL } 
 	};  
         Context_Item menu_geometry_elementary_scale[] = {
-	  { "0Geometry Elementary Scale", NULL } ,
+	  { "0Geometry > Elementary > Scale", NULL } ,
 	  { "Point",   (Fl_Callback *)geometry_elementary_scale_point_cb } ,
 	  { "Line",    (Fl_Callback *)geometry_elementary_scale_line_cb } ,
 	  { "Surface", (Fl_Callback *)geometry_elementary_scale_surface_cb } ,
 	  { NULL } 
 	};  
         Context_Item menu_geometry_elementary_symmetry[] = {
-	  { "0Geometry Elementary Symmetry", NULL } ,
+	  { "0Geometry > Elementary > Symmetry", NULL } ,
 	  { "Point",   (Fl_Callback *)geometry_elementary_symmetry_point_cb } ,
 	  { "Line",    (Fl_Callback *)geometry_elementary_symmetry_line_cb } ,
 	  { "Surface", (Fl_Callback *)geometry_elementary_symmetry_surface_cb } ,
 	  { NULL } 
 	};  
         Context_Item menu_geometry_elementary_extrude[] = {
-	  { "0Geometry Elementary Extrude", NULL } ,
+	  { "0Geometry > Elementary > Extrude", NULL } ,
 	  { "Translate", (Fl_Callback *)geometry_elementary_extrude_translate_cb } ,
 	  { "Rotate",    (Fl_Callback *)geometry_elementary_extrude_rotate_cb } ,
 	  { NULL } 
  	};  
             Context_Item menu_geometry_elementary_extrude_translate[] = {
-	      { "0Geometry Elementary Extrude Translate", NULL } ,
+	      { "0Geometry > Elementary > Extrude > Translate", NULL } ,
 	      { "Point",   (Fl_Callback *)geometry_elementary_extrude_translate_point_cb } ,
 	      { "Line",    (Fl_Callback *)geometry_elementary_extrude_translate_line_cb } ,
 	      { "Surface", (Fl_Callback *)geometry_elementary_extrude_translate_surface_cb } ,
 	      { NULL } 
 	    };  
             Context_Item menu_geometry_elementary_extrude_rotate[] = {
-	      { "0Geometry Elementary Extrude Rotate", NULL } ,
+	      { "0Geometry > Elementary > Extrude > Rotate", NULL } ,
 	      { "Point",   (Fl_Callback *)geometry_elementary_extrude_rotate_point_cb } ,
 	      { "Line",    (Fl_Callback *)geometry_elementary_extrude_rotate_line_cb } ,
 	      { "Surface", (Fl_Callback *)geometry_elementary_extrude_rotate_surface_cb } ,
 	      { NULL } 
 	    };  
         Context_Item menu_geometry_elementary_delete[] = {
-	  { "0Geometry Elementary Delete", NULL } ,
+	  { "0Geometry > Elementary > Delete", NULL } ,
 	  { "Point",   (Fl_Callback *)geometry_elementary_delete_point_cb } ,
 	  { "Line",    (Fl_Callback *)geometry_elementary_delete_line_cb } ,
 	  { "Surface", (Fl_Callback *)geometry_elementary_delete_surface_cb } ,
 	  { NULL } 
 	};  
     Context_Item menu_geometry_physical[] = {
-      { "0Geometry Physical", NULL } ,
+      { "0Geometry > Physical", NULL } ,
       { "Add",    (Fl_Callback *)geometry_physical_add_cb } ,
       { NULL } 
     };  
         Context_Item menu_geometry_physical_add[] = {
-	  { "0Geometry Physical Add", NULL } ,
+	  { "0Geometry > Physical > Add", NULL } ,
 	  { "Point",   (Fl_Callback *)geometry_physical_add_point_cb  } ,
 	  { "Line",    (Fl_Callback *)geometry_physical_add_line_cb  } ,
 	  { "Surface", (Fl_Callback *)geometry_physical_add_surface_cb  } ,
@@ -338,14 +338,14 @@ Context_Item menu_mesh[] = {
   { NULL } 
 };  
     Context_Item menu_mesh_define[] = {
-      { "1Mesh Define", NULL } ,
+      { "1Mesh > Define", NULL } ,
       { "Length",      (Fl_Callback *)mesh_define_length_cb  } ,
       { "Recombine",   (Fl_Callback *)mesh_define_recombine_cb  } ,
       { "Transfinite", (Fl_Callback *)mesh_define_transfinite_cb  } , 
       { NULL } 
     };  
         Context_Item menu_mesh_define_transfinite[] = {
-	  { "1Mesh Define Transfinite", NULL } ,
+	  { "1Mesh > Define > Transfinite", NULL } ,
 	  { "Line",    (Fl_Callback *)mesh_define_transfinite_line_cb } ,
 	  { "Surface", (Fl_Callback *)mesh_define_transfinite_surface_cb } ,
 	  { "Volume",  (Fl_Callback *)mesh_define_transfinite_volume_cb } , 
@@ -750,6 +750,10 @@ GUI::GUI(int argc, char **argv)
   context_geometry_window = NULL;
   context_mesh_window = NULL;
 
+  // initialize on-screen message buffer
+  onscreen_buffer[0][0] = '\0';
+  onscreen_buffer[1][0] = '\0';
+
   // set X display
   if(strlen(CTX.display))
     Fl::display(CTX.display);
@@ -1302,8 +1306,17 @@ void GUI::check_anim_buttons()
 
 void GUI::set_status(char *msg, int num)
 {
-  g_status_label[num]->label(msg);
-  g_status_label[num]->redraw();
+  if(num >= 0 && num < 3){
+    g_status_label[num]->label(msg);
+    g_status_label[num]->redraw();
+  }
+  else{
+    if(num == 3)
+      strncpy(onscreen_buffer[0], msg, 255);
+    if(num == 4)
+      strncpy(onscreen_buffer[1], msg, 255);
+    redraw_opengl();
+  }
 }
 
 // set the current drawing context 
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index b738faed7b..c9488c8b50 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -232,6 +232,9 @@ public:
   // solver windows
   SolverDialogBox  solver[5] ;
 
+  // on-screen persistent messages
+  char onscreen_buffer[2][256];
+
   // the constructor
   GUI(int argc, char **argv);
 
diff --git a/Fltk/Message.cpp b/Fltk/Message.cpp
index 6a64cc9853..92fe734ac1 100644
--- a/Fltk/Message.cpp
+++ b/Fltk/Message.cpp
@@ -1,4 +1,4 @@
-// $Id: Message.cpp,v 1.51 2004-05-15 15:32:32 geuzaine Exp $
+// $Id: Message.cpp,v 1.52 2004-05-18 17:00:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -90,6 +90,8 @@ void Msg(int level, char *fmt, ...)
   case STATUS2  : str = INFO_STR; verb = 1; window = 1; break ;
   case STATUS3N : log = 0; //fallthrough
   case STATUS3  : str = INFO_STR; verb = 1; window = 2; break ;
+  case ONSCREEN1: log = 0; verb = 1; window = 3; break ;
+  case ONSCREEN2: log = 0; verb = 1; window = 4; break ;
 
   case FATAL    : str = FATAL_STR; abort = 1; break ;
   case FATAL1   : str = FATAL_STR; break ;
@@ -125,7 +127,7 @@ void Msg(int level, char *fmt, ...)
 
 #define BUFFSIZE 1024
 
-  static char buff1[BUFFSIZE], buff2[BUFFSIZE], buff[4][BUFFSIZE];
+  static char buff1[BUFFSIZE], buff2[BUFFSIZE], buff[5][BUFFSIZE];
 
   if(CTX.verbosity >= verb) {
 
diff --git a/Fltk/Opengl.cpp b/Fltk/Opengl.cpp
index b44a6a98e1..4ce0b5768c 100644
--- a/Fltk/Opengl.cpp
+++ b/Fltk/Opengl.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl.cpp,v 1.39 2004-05-18 04:54:50 geuzaine Exp $
+// $Id: Opengl.cpp,v 1.40 2004-05-18 17:00:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -86,6 +86,25 @@ void Draw_String(char *s)
   }
 }
 
+void Draw_OnScreenMessages()
+{
+
+  glColor4ubv((GLubyte *) & CTX.color.fg);
+  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  double h = gl_height();
+  
+  if(strlen(WID->onscreen_buffer[0])){
+    double w = gl_width(WID->onscreen_buffer[0]);
+    glRasterPos2d(CTX.viewport[2]/2.-w/2., CTX.viewport[3] - 1.2*h);
+    gl_draw(WID->onscreen_buffer[0]);
+  }
+  if(strlen(WID->onscreen_buffer[1])){
+    double w = gl_width(WID->onscreen_buffer[1]);
+    glRasterPos2d(CTX.viewport[2]/2.-w/2., CTX.viewport[3] - 2.4*h);
+    gl_draw(WID->onscreen_buffer[1]);
+  }
+}
+
 // Euler angles set_XXX
 
 void set_r(int i, double val)
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index f9e903c638..57fa7c1d92 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.52 2004-05-17 17:40:03 geuzaine Exp $
+// $Id: Draw.cpp,v 1.53 2004-05-18 17:00:37 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -71,6 +71,7 @@ void Draw2d(void)
   glPushMatrix();
   Draw_Graph2D();
   Draw_Text2D();
+  Draw_OnScreenMessages();
   if(CTX.post.draw && CTX.post.scales)
     Draw_Scales();
   if(CTX.small_axes)
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 21de9ddd3b..1bbb2b957b 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -65,6 +65,7 @@ void Draw_Post(void);
 void Draw_Graph2D(void);
 void Draw_Text2D(void);
 void Draw_Text2D3D(int dim, int timestep, int nb, List_T *td, List_T *tc);
+void Draw_OnScreenMessages(void);
 void Draw_Scales(void);
 void Draw_Axes(double s);
 void Draw_SmallAxes(void);
diff --git a/doc/texinfo/gmsh.texi b/doc/texinfo/gmsh.texi
index 70ec720a73..669dc88955 100644
--- a/doc/texinfo/gmsh.texi
+++ b/doc/texinfo/gmsh.texi
@@ -1,5 +1,5 @@
 \input texinfo.tex @c -*-texinfo-*-
-@c $Id: gmsh.texi,v 1.107 2004-05-05 21:53:27 geuzaine Exp $
+@c $Id: gmsh.texi,v 1.108 2004-05-18 17:00:37 geuzaine Exp $
 @c
 @c Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 @c
@@ -2468,11 +2468,10 @@ purpose, e.g.@: Wordpad on Windows, or Emacs on Unix), it is almost always
 simpler to define the lines, the surfaces and the volumes interactively. To
 do so, just follow the context dependent buttons in the Geometry module. For
 example, to create a spline, select `Geometry' in the module menu, and then
-select `Elementary, Add, New, Spline'. You will then be asked (in the status
-bar of the graphic window) to select a list of points, and to type @kbd{e}
-to finish the selection (or @kbd{q} to abort it). Once the interactive
-command is completed, a string is automatically added at the end of the
-currently opened project file.
+select `Elementary, Add, New, Spline'. You will then be asked to select a
+list of points, and to type @kbd{e} to finish the selection (or @kbd{q} to
+abort it). Once the interactive command is completed, a string is
+automatically added at the end of the currently opened project file.
 
 Gmsh's second operating mode is the non-interactive mode. In this mode,
 there is no graphical user interface, and all operations are performed
-- 
GitLab