diff --git a/cat/src/cat.f90 b/cat/src/cat.f90
index 39f92071ef9879825583701824e7ceeecbec9dc7..12cc51730d3778afed510e2b5376779eb974b273 100644
--- a/cat/src/cat.f90
+++ b/cat/src/cat.f90
@@ -667,7 +667,8 @@ namelist /cat_nl/ nsteps    ,ngp       ,ngui    ,ingp    ,insp       , &
                   nforc     ,kfmin     ,kfmax   ,aforc    ,tforc     , &
                   myseed    ,ntseri    ,nstdout ,jacmthd  ,ndiag     , &
                   jac_scale ,nsp       ,outgp   ,outsp    ,tstp_mthd , &
-                  nsim      ,nuser     ,npost   ,npert    ,apert
+                  nsim      ,nuser     ,npost   ,npert    ,apert     , &
+                  nguidbg
 
 inquire(file=cat_namelist,exist=lcatnl)
 
@@ -1453,16 +1454,16 @@ call guiput("GQ" // char(0), ggui, ngx, ngy, 1)
 if (npost > 0) then
    !--- zonal means
    gguixm(:) = gqxm(:)   ! double -> single
-   call guiput("GQXM" // char(0), gguixm, 1, ngy, 1)   ! q 
+   call guiput("GQXM" // char(0), gguixm, ngy, 1, 1)   ! q 
 
    gguixm(:) = gpsixm(:) ! double -> single
-   call guiput("GPSIXM" // char(0), gguixm, 1, ngy, 1) ! psi 
+   call guiput("GPSIXM" // char(0), gguixm, ngy, 1, 1) ! psi 
 
    gguixm(:) = guxm(:) ! double -> single
-   call guiput("GUXM" // char(0), gguixm, 1, ngy, 1)   ! u
+   call guiput("GUXM" // char(0), gguixm, ngy, 1, 1)   ! u
 
    gguixm(:) = gvxm(:) ! double -> single
-   call guiput("GVXM" // char(0), gguixm, 1, ngy, 1)   ! v
+   call guiput("GVXM" // char(0), gguixm, ngy, 1, 1)   ! v
 
 
    !--- meridional means
diff --git a/cat/src/guix11.001 b/cat/src/guix11.001
new file mode 100644
index 0000000000000000000000000000000000000000..e198eb49347d71ebf13f3e4d19f89418f443179a
--- /dev/null
+++ b/cat/src/guix11.001
@@ -0,0 +1,4763 @@
+/*
+    guix11 - a GUI for PUMA, PLASIM & CAT 
+    2016 Edilbert Kirk & Hartmut Borth
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+int Debug = 0; // set in initgui
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+#define INT int
+#define REAL float
+#define INTXU unsigned int
+#define INTXS int
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define ROTATE_LEFT  (XK_Left)
+#define ROTATE_RIGHT (XK_Right)
+
+#define TOLELO 0x0001
+#define TOLEHI 0x0002
+#define TORILO 0x0004
+#define TORIHI 0x0008
+#define BOLELO 0x0010
+#define BOLEHI 0x0020
+#define BORILO 0x0040
+#define BORIHI 0x0080
+#define TOLEIN 0x0100
+#define TOREIN 0x0200
+#define BOLEIN 0x0400
+#define BOREIN 0x0800
+
+#define IPX(l,m,h) (VGAX * (x + (l-m) / (l-h)))
+#define IPY(l,m,h) (VGAY * (y + (l-m) / (l-h)))
+
+#define NUMWIN 9
+#define NUMPAL 13
+
+/* Picture types */
+
+#define ISOREC  0
+#define ISOHOR  1
+#define ISOCS   2
+#define ISOHOV  3
+#define ISOTS   4
+#define ISOTAB  5
+#define ISOSH   6
+#define ISOLON  7
+#define ISOTRA  8
+#define ISOCOL  9
+#define ISOROT 10
+#define MAPHOR 11
+#define MAPTRA 12
+
+/* Models */
+
+#define PUMA   0
+#define CAT    4
+
+char *IsoNames[] =
+{
+   "ISOREC",
+   "ISOHOR",
+   "ISOCS",
+   "ISOHOV",
+   "ISOTS",
+   "ISOTAB",
+   "ISOSH",
+   "ISOLON",
+   "ISOTRA",
+   "ISOCOL",
+   "ISOROT",
+   "MAPHOR",
+   "MAPTRA"
+};
+
+int IsoTypes = sizeof(IsoNames) / sizeof(char *);
+
+char *PalNames[] =
+{
+   "AUTO",
+   "U",
+   "V",
+   "T",
+   "P",
+   "Q",
+   "MARST",
+   "AMPLI",
+   "VEG",
+   "OCET",
+   "OCES",
+   "DCC",
+   "DTDT"
+};
+
+int PalTypes = sizeof(PalNames) / sizeof(char *);
+
+/* Map projections */
+
+#define CYLINDRICAL 0
+#define POLAR       1
+#define AZIMUTHAL   2
+
+#define MAXMAPS     3
+
+char *ProNames[] =
+{
+   "CYLINDRICAL",
+   "POLAR",
+   "AZIMUTHAL"
+};
+
+
+/* Coordinates of button areas */
+
+int ShowQueue = 0;
+int ShowOnce  = 1;
+int OffsetY = 20;
+
+int Stop_XL;
+int Stop_XH;
+int Stop_YL;
+int Stop_YH;
+
+int Start_XL;
+int Start_XH;
+int Start_YL;
+int Start_YH;
+
+int Pause_XL;
+int Pause_XH;
+int Pause_YL;
+int Pause_YH;
+
+int Help_XL;
+int Help_XH;
+int Help_YL;
+int Help_YH;
+
+int Minus_XL;
+int Minus_XH;
+int Minus_YL;
+int Minus_YH;
+
+int FBWD_XL;
+int FBWD_XH;
+int FBWD_YL;
+int FBWD_YH;
+
+int Plus_XL;
+int Plus_XH;
+int Plus_YL;
+int Plus_YH;
+
+int FFWD_XL;
+int FFWD_XH;
+int FFWD_YL;
+int FFWD_YH;
+
+int Parc_XL;
+int Parc_XH;
+int Parc_XD;
+int Parc_YL;
+int Parc_YH;
+int Parc_YD;
+
+int Wbox_XL;
+int Wbox_XH;
+int Wbox_YL;
+int Wbox_YH;
+
+int Grid_XL;
+int Grid_XH;
+int Grid_YL;
+int Grid_YH;
+
+XPoint StopButton[4] = {{10,10},{40,10},{40,40},{10,40}};
+XPoint StartButton[3] = {{50,10},{80,25},{50,40}};
+XPoint PauseButton1[4] = {{95,10},{102,10},{102,40},{95,40}};
+XPoint PauseButton2[4] = {{108,10},{115,10},{115,40},{108,40}};
+
+#define PARCS 100
+
+struct ParcStruct
+{
+   char Name[8];
+   float Inc;
+   float Min;
+   float Max;
+   float Val;
+};
+
+int Parcs;
+int cpi = 1;
+
+struct ParcStruct Parc[PARCS];
+
+int screen_num;
+
+Display *display;
+unsigned int ScreenW,ScreenH,ScreenBot;
+int SmallScreen;
+
+static char *progname = "PUMA";
+
+int BigEndian;
+int ScreenOffset;
+int Model;
+int CowX = -1;
+int CowY = -1;
+int CowW;
+int CowH;
+int NumWin = NUMWIN;
+int WinCols = 3;
+int WinRows = 3;
+int DimT = 100; // Default length of time axis
+int DimX;
+int DimY;
+int DimZ;
+int DimXY;
+int Uindex = -1;
+int Vindex = -1;
+int ScreenD;
+int OffX;
+int OffY = 0;
+INTXU WinXSize;
+INTXU WinYSize;
+int InXSize;
+int InYSize;
+int Latitudes;
+int Lines;
+int SizeChanged;
+int Shutdown;
+int Grid = 1;
+int GridLabel = 1;
+int WhitePix;
+int BlackPix;
+int *Flag;
+int FlagSize;
+int nstep;
+int MRpid;
+int MRnum;
+int wto;
+int FirstKey;
+int LastKey;
+int SymsPerKey;
+
+REAL arx;
+REAL ary;
+
+KeySym *KeyMap;
+
+char wtrun[8];
+
+unsigned Seed;
+
+float RotInc = 0.2;
+int LineCo[NUMPAL];
+int MapPro[NUMWIN];
+int HovInx[NUMWIN];
+int Indez[NUMWIN];
+int MaxZ[NUMWIN];
+int RedrawFlag[NUMWIN];
+int LevelChanged[NUMWIN];
+int RotLon[NUMWIN];
+double AutoDelta[NUMWIN];
+double AutoXdelt[NUMWIN];
+double AutoLo[NUMWIN];
+REAL *TSdata[NUMWIN];
+REAL *Dmin[NUMWIN];
+REAL *Dmax[NUMWIN];
+REAL *SpeedScale;
+XPoint *TSxp[NUMWIN];
+
+
+#define MAXPAR 16384
+float pax[MAXPAR];
+float pay[MAXPAR];
+long  pal[MAXPAR];
+
+int Delpar = 8; /* Interval for particle injection */
+int ParInd = 0;
+int ColInd = 0;
+long TracerColor;
+
+#define NUMSCALARS 9
+
+char TSName[NUMSCALARS][80];
+char TSubsc[NUMSCALARS][80];
+char TSUnit[NUMSCALARS][80];
+char TScale[NUMSCALARS][80];
+
+struct PixStruct
+{
+   int DimX;
+   int DimY;
+   Pixmap Pix;
+} WinPixMap[NUMWIN];
+
+Pixmap pix;
+
+#define NUMARRAYS 100
+
+struct ArrayStruct
+{
+   char Name[80];
+   float *Data;
+   int DimX;
+   int DimY;
+   int DimZ;
+   int Flag;
+} Array[NUMARRAYS];
+
+int NumArrays;
+
+struct WinAttStruct
+{
+   unsigned int x;
+   unsigned int y;
+   unsigned int w;
+   unsigned int h;
+   int active;
+   char array_name[80];
+   int Plot;
+   int Palette;
+} WinAtt[NUMWIN];
+
+int BorderWidth =  0;
+int WM_top_area =  0; // Window manager top    area
+int WinLM       =  0;
+int WinRM       =  0;
+int WinTM       = 24;
+int WinBM       =  0;
+
+struct ColorStrip
+{
+   double  Lo;
+   double  Hi;
+   char *Name;
+   unsigned long pixel;
+};
+
+#define AUTOCOLORS 14
+struct ColorStrip Autostrip[AUTOCOLORS+1] =
+{
+   {0.0,0.0,"red"},
+   {0.0,0.0,"OrangeRed"},
+   {0.0,0.0,"Orange"},
+   {0.0,0.0,"yellow"},
+   {0.0,0.0,"GreenYellow"},
+   {0.0,0.0,"green"},
+   {0.0,0.0,"aquamarine"},
+   {0.0,0.0,"cyan"},
+   {0.0,0.0,"SkyBlue"},
+   {0.0,0.0,"blue"},
+   {0.0,0.0,"orchid"},
+   {0.0,0.0,"magenta"},
+   {0.0,0.0,"violet"},
+   {0.0,0.0,"DarkViolet"},
+   {0.0,0.0,NULL}
+};
+
+struct ColorStrip Ustrip[] =
+{
+   {-99.0,-10.0,"red"},
+   {-10.0, -5.0,"OrangeRed"},
+   { -5.0,  0.0,"Orange"},
+   {  0.0,  5.0,"yellow"},
+   {  5.0, 10.0,"GreenYellow"},
+   { 10.0, 15.0,"green"},
+   { 15.0, 20.0,"aquamarine"},
+   { 20.0, 25.0,"cyan"},
+   { 25.0, 30.0,"SkyBlue"},
+   { 30.0, 35.0,"blue"},
+   { 35.0, 40.0,"orchid"},
+   { 40.0, 45.0,"magenta"},
+   { 45.0, 50.0,"violet"},
+   { 50.0, 99.0,"DarkViolet"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip Qstrip[] =
+{
+   {-99.0,  0.0,"black"},
+   {  0.0,  5.0,"OrangeRed"},
+   {  5.0, 10.0,"Orange"},
+   { 10.0, 15.0,"yellow"},
+   { 15.0, 20.0,"GreenYellow"},
+   { 20.0, 25.0,"green"},
+   { 25.0, 30.0,"aquamarine"},
+   { 30.0, 35.0,"cyan"},
+   { 35.0, 40.0,"SkyBlue"},
+   { 40.0, 45.0,"blue"},
+   { 45.0, 50.0,"orchid"},
+   { 50.0, 55.0,"magenta"},
+   { 55.0, 60.0,"violet"},
+   { 60.0, 99.0,"DarkViolet"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip Vstrip[] =
+{
+   {-99.0,-10.0,"brown"},
+   {-10.0, -8.0,"gold"},
+   { -8.0, -6.0,"purple"},
+   { -6.0, -4.0,"red"},
+   { -4.0, -2.0,"OrangeRed"},
+   { -2.0,  0.0,"Orange"},
+   {  0.0,  2.0,"yellow"},
+   {  2.0,  4.0,"GreenYellow"},
+   {  4.0,  6.0,"green"},
+   {  6.0,  8.0,"aquamarine"},
+   {  8.0, 10.0,"cyan"},
+   { 10.0, 99.0,"blue"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip Tstrip[] =
+{
+   {-99.0,-50.0,"MidnightBlue"},
+   {-50.0,-40.0,"RoyalBlue4"},
+   {-40.0,-30.0,"RoyalBlue3"},
+   {-30.0,-20.0,"RoyalBlue2"},
+   {-20.0,-10.0,"RoyalBlue1"},
+   {-10.0,  0.0,"violet"},
+   {  0.0, 10.0,"IndianRed1"},
+   { 10.0, 20.0,"IndianRed2"},
+   { 20.0, 30.0,"IndianRed3"},
+   { 30.0, 40.0,"IndianRed4"},
+   { 40.0, 50.0,"red"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip Kstrip[] =
+{
+   {100.0,210.0,"RoyalBlue4"},
+   {210.0,220.0,"RoyalBlue3"},
+   {220.0,230.0,"RoyalBlue2"},
+   {230.0,240.0,"RoyalBlue1"},
+   {240.0,250.0,"violet"},
+   {250.0,260.0,"IndianRed1"},
+   {260.0,270.0,"IndianRed2"},
+   {270.0,280.0,"IndianRed3"},
+   {280.0,290.0,"IndianRed4"},
+   {290.0,400.0,"red"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip Pstrip[] =
+{
+   {  00.0, 985.0,"RoyalBlue4"},
+   { 985.0, 990.0,"RoyalBlue3"},
+   { 990.0, 995.0,"RoyalBlue2"},
+   { 995.0,1000.0,"RoyalBlue1"},
+   {1000.0,1005.0,"violet"},
+   {1005.0,1010.0,"IndianRed1"},
+   {1010.0,1015.0,"IndianRed2"},
+   {1015.0,1020.0,"IndianRed3"},
+   {1020.0,1025.0,"IndianRed4"},
+   {1025.0,9990.0,"red"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip MarsTStrip[] =
+{
+   {-200.0,-90.0,"RoyalBlue4"},
+   { -90.0,-80.0,"RoyalBlue3"},
+   { -80.0,-70.0,"RoyalBlue2"},
+   { -70.0,-60.0,"RoyalBlue1"},
+   { -60.0,-50.0,"violet"},
+   { -50.0,-40.0,"IndianRed1"},
+   { -40.0,-30.0,"IndianRed2"},
+   { -30.0,-20.0,"IndianRed3"},
+   { -20.0,  0.0,"IndianRed4"},
+   {   0.0,100.0,"red"},
+   {   0.0,  0.0,NULL}
+};
+
+struct ColorStrip AmpliStrip[] =
+{
+   {   0.0,  1.0,"DarkBlue"},
+   {   8.0,  9.0,"blue"},
+   {   8.0,  9.0,"DarkGreen"},
+   {   8.0,  9.0,"green"},
+   {   8.0,  9.0,"yellow"},
+   {   9.0, 10.0,"Orange"},
+   {  10.0, 11.0,"OrangeRed"},
+   {  11.0, 12.0,"red"},
+   {   0.0,  0.0,NULL}
+};
+
+struct ColorStrip Vegstrip[] =
+{
+   {-999.9,0.001,"DarkBlue"},
+   { 0.001, 10.0,"brown"},
+   {  10.0, 20.0,"SeaGreen4"},
+   {  20.0, 30.0,"SeaGreen3"},
+   {  30.0, 40.0,"SeaGreen2"},
+   {  40.0, 50.0,"SeaGreen1"},
+   {  50.0, 60.0,"YellowGreen"},
+   {  60.0, 70.0,"green4"},
+   {  70.0, 80.0,"green3"},
+   {  80.0, 90.0,"green2"},
+   {  90.0,999.0,"green1"},
+   {   0.0,  0.0,NULL}
+};
+
+struct ColorStrip Tstripoce[] =
+{
+   {-99.0, 0.00001,"Black"},
+   { 0.00001, 4.0 ,"RoyalBlue4"},
+   { 4.0 ,8.0,"RoyalBlue3"},
+   { 8.0, 12.0,"RoyalBlue2"},
+   { 12.0, 16.0,"RoyalBlue1"},
+   { 16.0, 20.0,"violet"},
+   { 20.0, 24.0,"IndianRed1"},
+   { 24.0, 28.0,"IndianRed2"},
+   { 28.0, 32.0,"IndianRed3"},
+   { 32.0, 36.0,"IndianRed4"},
+   { 36.0, 40.0,"red"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip Sstripoce[] =
+{
+   {-99.0, 30.0,"Black"},
+   { 30.0, 32.0 ,"RoyalBlue4"},
+   { 32.0 ,32.5,"RoyalBlue3"},
+   { 32.5, 33.0,"RoyalBlue2"},
+   { 33.0, 34.0,"SeaGreen"},
+   { 34.0, 34.5,"YellowGreen"},
+   { 34.5, 35.0,"LightGreen"},
+   { 35.0, 35.5,"Orange"},
+   { 35.5, 36.0,"DarkOrange"},
+   { 36.0, 36.5,"OrangeRed"},
+   { 36.5, 40.0,"red"},
+   {  0.0,  0.0,NULL}
+};
+
+struct ColorStrip DCCstrip[] =
+{
+   {-99.0, 0.0, "Black"},
+   {  0.0, 10.0,"Yellow"},
+   { 10.0, 20.0,"YellowGreen"},
+   { 20.0, 30.0,"Green"},
+   { 30.0, 40.0,"Aquamarine"},
+   { 40.0, 50.0,"Cyan"},
+   { 50.0, 60.0,"SkyBlue"},
+   { 60.0, 70.0,"Blue"},
+   { 70.0, 80.0,"Orchid"},
+   { 80.0, 90.0,"Magenta"},
+   { 90.0,100.0,"DarkViolet"},
+   { 0.0, 0.0,NULL}
+};
+
+struct ColorStrip DTDTstrip[] =
+{
+   {-99.0,  -5.0,"brown"},
+   {- 5.0,  -3.0,"gold"},
+   { -3.0,  -1.5,"purple"},
+   { -1.5,  -0.5,"red"},
+   { -0.5,  -0.25,"OrangeRed"},
+   { -0.25,  0.0,"Orange"},
+   {  0.0,   0.25,"yellow"},
+   {  0.25,  0.5,"GreenYellow"},
+   {  0.5,   1.5,"green"},
+   {  1.5,   3.0,"aquamarine"},
+   {  3.0,   5.0,"cyan"},
+   {  5.0, 99.0,"blue"},
+   {  0.0,  0.0,NULL}
+};
+
+#define AMPLI_COLS 8
+
+struct ColorStrip *Cstrip;
+struct ColorStrip *Pallet[NUMPAL] =
+{ Autostrip, Ustrip, Vstrip, Tstrip, Pstrip, Qstrip,MarsTStrip,AmpliStrip,
+  Vegstrip, Tstripoce, Sstripoce, DCCstrip, DTDTstrip};
+
+REAL VGAX;
+REAL VGAY;
+REAL CurVal;
+
+REAL *Field;  // Pointer for ISO data
+REAL *Ampli;  // Amplitudes of spherical harmonics
+XColor *Acol; // Amplitude colors
+
+Colormap colormap;
+
+XColor xcolor1,xcolor2;
+XColor Red,Green,Blue,Yellow,Grey,LightRed,DarkRed,LightBlue,DarkBlue;
+XColor LightGreen,DarkGreen,Dummy;
+
+unsigned long TSColor[10];
+
+Window Win[NUMWIN];
+int    win; // Current window
+Window Cow; // Control bar
+Window HelpWindow;
+
+XTextProperty WinconName1;
+XTextProperty WinconName3;
+XTextProperty WinconPause;
+XTextProperty WinconReady;
+char *PauseTitle = "Run Paused";
+char *ReadyTitle = "Press Start Button";
+
+XEvent CowEvent;
+
+XSizeHints WinSizeHints;
+XSizeHints CowSizeHints;
+int OutXSize,OutYSize;
+int count;
+XEvent report;
+GC gc;
+
+/*
+char BigFontName[80] = "10x20";
+char FixFontName[80] = "9x15bold";
+char SubFontName[80] = "6x10";
+*/
+char BigFontName[80] = "9x15bold";
+char FixFontName[80] = "8x13";
+char SubFontName[80] = "6x10";
+
+XFontStruct *FixFont;
+XFontStruct *SubFont;
+XFontStruct *BigFont;
+int FixFontHeight;
+int SubFontHeight;
+int BigFontHeight;
+int FixFontWidth;
+int SubFontWidth;
+int BigFontWidth;
+int Paused = 0;
+
+char *display_name = NULL;
+XWMHints wm_hints;
+XClassHint class_hints;
+Atom Delwin;
+
+char *WindowTitle[NUMWIN];
+XTextProperty WindowName[NUMWIN];
+XTextProperty HelpName;
+
+char *mona[12] =
+{
+   "Jan","Feb","Mar",
+   "Apr","May","Jun",
+   "Jul","Aug","Sep",
+   "Oct","Nov","Dec"
+};
+
+char *wena[7] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
+
+char datch[64];
+char PlanetName[32];
+
+char GUI_default[80] = "GUI.cfg";
+char GUI_config[80] = "GUI_last_used.cfg";
+
+
+#define PSDIM 30
+char *pixelstar[PSDIM]  = {
+"..............................",
+"..............................",
+"..............................",
+"...**....**....**....**.......",
+"...**....**....**....**.......",
+"...**....**....**....**.......",
+"...**....**....**....**.......",
+"...**....**************.......",
+"...**....**************.......",
+"...**....**....**....**.......",
+"...***...**....**....**.......",
+"....******.....**....**.......",
+".....****......**....**.......",
+"..............................",
+"..............................",
+"..............................",
+"..............................",
+"..............................",
+"..............................",
+"..............................",
+"..............................",
+"..............................",
+".......................*......",
+"......................***.....",
+"...................**.***.**..",
+"...................**.***.**..",
+"...................**.***.**..",
+"...................****.****..",
+"...................***...***..",
+"...................***...***.."};
+
+// Variables used for calculating "frames per second"
+
+int fps;
+int rmuf = 20;  // Rotating map update frequency [1/sec]
+int rmui =  1;  // Rotating map update interval  [steps]
+int SkipFreq;
+int ThisSecond;
+int LastSecond;
+int LastStep;
+int SecEvent;
+
+int ndatim[6];  /* year, month, day, hour, minute, weekday */
+int LastMinute; /* Last value of ndatim(4)                 */
+int DeltaTime ; /* Computed timestep interval [min]        */
+
+struct BMIstruct
+{
+   int   Size;
+   int   Width;
+   int   Height;
+   short Planes;
+   short Count;
+   int   Compression;
+   int   SizeImage;
+   int   XPelsPerMeter;
+   int   YPelsPerMeter;
+   int   ClrUsed;
+   int   ClrImportant;
+};
+
+struct BMIstruct ImageBMI;
+
+struct MapImageStruct
+{
+   char   *d; // Bitmap data
+   int     w; // Image width
+   int     h; // Image height
+   int     f; // Rotation factor
+   float   l; // Reference longitude
+   float   r; // Rotation speed [deg/step]
+   XImage *X; // XImage structure
+};
+
+// Convert an RGB value to an X11 Pixel
+
+unsigned long create_pixel(long red, long green, long blue)
+{
+   if (ScreenD == 24)       // 24 bit true color
+   {
+       return blue | green << 8 | red << 16;
+   }
+   else if (ScreenD == 16)  // 16 bit RGB 565
+   {
+      return blue >> 3 | (green >> 2) << 5 | (red >> 3) << 11;
+   }
+   else return 0;
+}
+
+struct MapImageStruct MapHR; // Hires (2560x1280) Earth image
+struct MapImageStruct MapLR[NUMWIN];
+
+void ScaleImage(struct MapImageStruct *s, struct MapImageStruct *d)
+{
+   int a,b,x,y;
+   unsigned long px;
+   unsigned long h,w;
+   double f,g;
+
+   if (d->X) XDestroyImage(d->X);
+   w = (d->w + 7) & 0xFFF8;
+   h =  d->h;
+   d->d = malloc(4 * w * h);
+   d->X = XCreateImage(display,CopyFromParent,ScreenD,ZPixmap,0,
+                  d->d,w,h,8,0);
+
+   f = (double)s->w / (double)d->w;
+   g = (double)s->h / (double)d->h;
+
+   for (y = 0 ; y < d->h ; ++y)
+   for (x = 0 ; x < d->w ; ++x)
+   {
+       a = x * f;
+       b = y * g;
+       XPutPixel(d->X,x,y,XGetPixel(s->X,a,b));
+   }
+}
+
+
+void PolarImage(struct MapImageStruct *s, struct MapImageStruct *d)
+{
+   int a,b,x,y;
+   unsigned long h,w;
+   double f,lfa,xnp,ynp,xsp,ysp,dx,dy;
+
+   if (d->X) XDestroyImage(d->X);
+   w = (d->w + 7) & 0xFFF8;
+   h =  d->h;
+   d->d = malloc(4 * w * h);
+   d->X = XCreateImage(display,CopyFromParent,ScreenD,ZPixmap,0,
+                  d->d,w,h,8,0);
+
+   f   = ary * (double)s->h / (double)d->h;
+   lfa = (s->w-1) / (2.0 * M_PI);
+   xnp = (d->w) * 0.25;
+   ynp = (d->h) * 0.50;
+   xsp = (d->w) * 0.75;
+   ysp = ynp;
+
+   for (y = 0 ; y < d->h   ; ++y)
+   {
+      dy = (ynp - y);
+      for (x = 0 ; x < d->w/2 ; ++x) /* Northern hemisphere */
+      {
+         dx = (xnp - x);
+         a = atan2(dx,dy) * lfa;
+         b = sqrt(dx * dx + dy * dy) * f;
+         if (a < 0.0) a += (s->w);
+         if (a >= 0 && a < s->w && b >= 0 && b <= s->h/2)
+              XPutPixel(d->X,x,y,XGetPixel(s->X,a,b));
+         else XPutPixel(d->X,x,y,BlackPix);
+      }
+      dy = (ysp - y);
+      for (x = d->w/2 ; x < d->w ; ++x) /* Southern hemisphere */
+      {
+         dx =(x - xsp);
+         a = atan2(dx,dy) * lfa;
+         b = s->h - f * sqrt(dx * dx + dy * dy);
+         if (a < 0.0) a += (s->w);
+         if (a >= 0 && a < s->w && b >= 0 && b >= s->h/2 && b <= s->h)
+              XPutPixel(d->X,x,y,XGetPixel(s->X,a,b));
+         else XPutPixel(d->X,x,y,BlackPix);
+      }
+   }
+}
+
+
+void RevOrtho(double R, double lam0, double phi0, int xx, int yy, double *lam, double *phi)
+{
+   double rho,c,rhoq,x,y;
+
+   x = xx;
+   y = yy;
+
+   rhoq = x*x + y*y;
+   rho  = sqrt(rhoq);
+   if (rho > R)
+   {
+      *phi = 999.9;
+      *lam = 999.9;
+   }
+   else if (rho > R / 100000.0)
+   {
+      c   = asin(rho / R);
+      *phi = asin(cos(c) * sin(phi0) + y * sin(c) * cos(phi0) / rho);
+      *lam = lam0 + atan2(x * sin(c) , rho * cos(phi0) * cos(c) - y * sin(phi0) * sin(c));
+   }
+   else
+   {
+      *phi = phi0;
+      *lam = lam0;
+   }
+   // printf("[%6.1lf / %6.1lf] --> (%6.1lf / %6.1lf)\n",x,y,*lam,*phi);
+}
+
+/* ==================================================== */
+/* AzimuthalImage - Display map in azimuthal projection */
+/* ==================================================== */
+
+void AzimuthalImage(struct MapImageStruct *s, struct MapImageStruct *d)
+{
+   int lam;           // lambda pixel coordinate in source image
+   int phi;           // phi    pixel coordinate in source image
+   int x  ;           // x      pixel coordinate in destination image
+   int y  ;           // y      pixel coordinate in destination image
+   int dxc;           // pixel coordinate of centre     position
+   int dxl;           // pixel coordinate of left  most position
+   int dxr;           // pixel coordinate of right most position
+   int dx ;           // centre relative x position
+   int dy ;           // centre relative y position
+   int p00;           // euqator
+   int l00;           // reference longitude
+   
+   unsigned int dih;  // destination image height
+   unsigned int diw;  // destination image width
+   unsigned int dpw;  // destination image padded width
+
+   double rad;        // pixel radius of new image
+   double ysc;        // yscale = source height / destination height
+   double rho;        // distance from centre
+   double xpi;        // x scale factor = 2 * PI / width
+   double ypi;        // y scale factor =     PI / height
+   double xrf;
+   double yrf;
+
+   XImage *sX;        // source      image
+   XImage *dX;        // destination image
+
+
+   // Destroy old image structure inclusive data storage
+
+   if (d->X) XDestroyImage(d->X);
+
+   // Set width of new image
+
+   diw = d->w;
+
+   // Pad width of new image to a multiple of 8
+
+   dpw = (diw + 7) & 0xFFF8;
+
+   // Set height of new image
+
+   dih =  d->h;
+
+   // Allocate space for image data
+
+   d->d = calloc(dpw * dih,4);
+
+   // Create image structure
+
+   dX = d->X = XCreateImage(display,CopyFromParent,ScreenD,ZPixmap,0,d->d,dpw,dih,8,0);
+   sX = s->X;
+
+   p00 = s->h >> 1;
+   rad = dih  >> 1;
+   dxc = diw  >> 1;
+   dxl = MAX(dxc - rad,   0);
+   dxr = MIN(dxc + rad, diw);
+   xpi = s->w / M_PI * 0.5;
+   ypi = s->h / M_PI;
+   ysc = (double)s->h / (double)dih;
+   l00 = (int)((d->l * s->w) / 360 + s->w/2) % s->w;
+   xrf = (double)diw / pow(2.0,31),
+   yrf = (double)dih / pow(2.0,31);
+
+   // Paint some stars on the sky
+
+   srandom(Seed);
+   for (y = 0 ; y < (diw * dih) >> 8  ; ++y)
+      XPutPixel(dX,xrf*random(),yrf*random(),WhitePix);
+
+   for (y = 0 ; y < dih ; ++y)
+   {
+      dy  = y - rad;
+      phi = y * ysc;
+      for (x = dxl ; x < dxr ; ++x)
+      {
+         dx = x - dxc;
+         rho = sqrt(dx * dx + dy * dy);
+         if (rho < rad)
+         {
+            lam = l00 + xpi * atan2(dx / rad, cos(asin(rho / rad)));
+            phi = p00 + ypi *  asin(dy / rad);
+            XPutPixel(dX,x,y,XGetPixel(sX,lam,phi));
+         }
+      }
+   }
+}
+
+
+void SwapIEEE16(char W[2])
+{
+   char B;
+
+   B = W[0]; W[0] = W[1]; W[1] = B; 
+}
+
+void SwapIEEE32(char W[4])
+{
+   char B;
+
+   B = W[0]; W[0] = W[3]; W[3] = B; 
+   B = W[1]; W[1] = W[2]; W[2] = B; 
+}
+
+int ReadINT(FILE *fpi)
+{
+   int i,k;
+   i = fread(&k,sizeof(k),1,fpi);
+   if (BigEndian) SwapIEEE32((char *)&k);
+   return k;
+}
+
+short ReadSHORT(FILE *fpi)
+{
+   short i,k;
+   i = fread(&k,sizeof(k),1,fpi);
+   if (BigEndian) SwapIEEE16((char *)&k);
+   return k;
+}
+
+void ReadImage(struct MapImageStruct *ei, char *filename)
+{
+   char ch;
+   int i,n,x,y,z;
+   long r,g,b;
+   int FileSize;
+   int Reserved;
+   int OffBits;
+   int PicBytes;
+   int ImgBytes;
+   int PadWidth;
+   int PadBytes;
+   int bpp;
+   int byr;
+   FILE *fp;
+   unsigned char *BuffImageData;
+
+   if (!(fp = fopen(filename,"r"))) return;
+   ch = fgetc(fp);
+   if (ch != 'B') return;
+   ch = fgetc(fp);
+   if (ch != 'M') return;
+   FileSize = ReadINT(fp);
+   Reserved = ReadINT(fp);
+   OffBits  = ReadINT(fp);
+
+   if (Debug)
+   {
+      printf("Properties of %s:\n",filename);
+      printf("FileSize   = %d\n",FileSize);
+      printf("FileOffset = %d\n",OffBits);
+   }
+
+   ImageBMI.Size          = ReadINT(fp);
+   ImageBMI.Width         = ReadINT(fp);
+   ImageBMI.Height        = ReadINT(fp);
+   ImageBMI.Planes        = ReadSHORT(fp);
+   ImageBMI.Count         = ReadSHORT(fp);
+   ImageBMI.Compression   = ReadINT(fp);
+   ImageBMI.SizeImage     = ReadINT(fp);
+   ImageBMI.XPelsPerMeter = ReadINT(fp);
+   ImageBMI.YPelsPerMeter = ReadINT(fp);
+   ImageBMI.ClrUsed       = ReadINT(fp);
+   ImageBMI.ClrImportant  = ReadINT(fp);
+
+   PadWidth = (ImageBMI.Width + 7) & 0xFFF8;
+   bpp      =  ImageBMI.Count >> 3;
+   PadBytes = (4 - ((ImageBMI.Width * bpp) % 4)) % 4 ;
+
+   if (Debug)
+   {
+      printf("BMI Size     = %d\n",ImageBMI.Size);
+      printf("BMI Width    = %d\n",ImageBMI.Width);
+      printf("BMI Height   = %d\n",ImageBMI.Height);
+      printf("BMI Planes   = %d\n",ImageBMI.Planes);
+      printf("BMI Count    = %d\n",ImageBMI.Count);
+      printf("BMI ClrUsed  = %d\n",ImageBMI.ClrUsed);
+      printf("Pad Bytes    = %d\n",PadBytes);
+      printf("ScreenD= %d\n",ScreenD);
+   }
+
+   PicBytes = (bpp * ImageBMI.Width + PadBytes) * ImageBMI.Height;
+   ImgBytes = 4 * PadWidth * ImageBMI.Height;
+   ei->d = calloc(ImgBytes,1);
+   BuffImageData = malloc(PicBytes);
+   fseek(fp,OffBits,SEEK_SET);
+   n = fread(BuffImageData,PicBytes,1,fp);
+   fclose(fp);  
+   
+   ei->X = XCreateImage(display,CopyFromParent,ScreenD,ZPixmap,0,
+                  ei->d,PadWidth,ImageBMI.Height,8,0);
+
+   for (y = 0 ; y < ImageBMI.Height ; ++y)
+   for (x = 0 ; x < ImageBMI.Width  ; ++x)
+   {
+       i = bpp * x + (ImageBMI.Height - 1 - y) * (ImageBMI.Width*bpp+PadBytes);
+       b = BuffImageData[i  ];
+       g = BuffImageData[i+1];
+       r = BuffImageData[i+2];
+       XPutPixel(ei->X, x, y, create_pixel(r,g,b));
+   }
+   free(BuffImageData);
+   ei->w = ImageBMI.Width;
+   ei->h = ImageBMI.Height;
+}
+
+
+void ntocdat(void)
+{
+   if (ndatim[1] > 0)
+   {
+      if (ndatim[5] >= 0)
+         sprintf(datch,"%s %2d-%s-%04d %2d:%02d",wena[ndatim[5]],ndatim[2],mona[ndatim[1]-1],
+           ndatim[0],ndatim[3],ndatim[4]);
+      else
+      sprintf(datch,"%2d-%s-%04d %2d:%02d",ndatim[2],mona[ndatim[1]-1],
+           ndatim[0],ndatim[3],ndatim[4]);
+   }
+}
+
+/* ============================================== */
+/* CharAlloc - Allocate space for character array */
+/* ============================================== */
+
+char *CharAlloc(int bytes,char *array_name)
+{
+   char *result = NULL;
+   if (bytes > 0)
+   {
+      result = (char *)calloc(bytes, sizeof(char));
+      if (!result || Debug)
+      {
+         if (!result) printf("*** Out of Memory *** on ");
+         printf("CharAlloc:  at%10p %6d char for %-30.30s\n",
+                result,bytes,array_name);
+      }
+   }
+   return(result);
+}
+
+/* ======================================= */
+/* IntAlloc - Allocate space for int array */
+/* ======================================= */
+
+int *IntAlloc(int words,char *array_name)
+{
+   int *result = NULL;
+   if (words > 0)
+   {
+      result = (int *) calloc(words, sizeof(int));
+      if (!result || Debug)
+      {
+         if (!result) printf("*** Out of Memory *** on ");
+         printf("IntAlloc:   at%10p %6d int for %s\n",
+               result,words,array_name);
+      }
+   }
+   return(result);
+}
+
+/* =========================================== */
+/* FloatAlloc - Allocate space for float array */
+/* =========================================== */
+
+float *FloatAlloc(int words, char *array_name)
+{
+   float *result = NULL;
+   if (words > 0)
+   {
+      result = (float *) calloc(words, sizeof(float));
+      if (!result || Debug)
+      {
+         if (!result) printf("*** Out of Memory *** on ");
+         printf("FloatAlloc: at%10p %6d float for %s\n",
+               result,words,array_name);
+      }
+   }
+   return(result);
+}
+
+/* ========================================== */
+/* SizeAlloc - Allocate space for sized array */
+/* ========================================== */
+
+void *SizeAlloc(int words, int Size, char *array_name)
+{
+   void *result = NULL;
+   if (words > 0)
+   {
+      result = (void *) calloc(words, Size);
+      if (!result || Debug)
+      {
+         if (!result) printf("*** Out of Memory *** on ");
+         printf("SizeAlloc:  at%10p %6d void for %s\n",
+               result,words,array_name);
+      }
+   }
+   return(result);
+}
+
+void LoadFonts(void)
+{
+   if ((FixFont = XLoadQueryFont(display,FixFontName)) == NULL)
+   {
+      printf("%s: Cannot open %s font\n",progname,FixFontName);
+      exit(-1);
+   }
+   if ((SubFont = XLoadQueryFont(display,SubFontName)) == NULL)
+   {
+      SubFont = FixFont;
+   }
+   if ((BigFont = XLoadQueryFont(display,BigFontName)) == NULL)
+   {
+      if ((BigFont = XLoadQueryFont(display,"10x20")) == NULL)
+      {
+         printf("%s: Cannot open %s font\n",progname,BigFontName);
+         exit(-1);
+      }
+   }
+   FixFontWidth  = XTextWidth(FixFont,"X",1);
+   SubFontWidth  = XTextWidth(SubFont,"X",1);
+   BigFontWidth  = XTextWidth(BigFont,"X",1);
+   FixFontHeight = FixFont->ascent + FixFont->descent;
+   SubFontHeight = SubFont->ascent + SubFont->descent;
+   BigFontHeight = BigFont->ascent + BigFont->descent;
+}
+
+int AllocateColorCells(struct ColorStrip cs[])
+{
+   int i = 0;
+   XColor xcolor1,xcolor2;
+
+   while (cs[i].Name)
+   {
+      XAllocNamedColor(display,colormap,cs[i].Name,&xcolor1,&xcolor2);
+      cs[i].pixel = xcolor1.pixel;
+      ++i;
+   }   
+   return i;
+}
+
+void CalcButtonAreas(void)
+{
+   int of,ds,bh,fh,fw,j;
+
+   of = OffsetY;
+   ds = 10;
+   bh = 30;
+   fh = BigFontHeight;
+   fw = BigFontWidth;
+
+   /* 1. Stop Button */
+
+   StopButton[0].y += OffsetY;
+   StopButton[1].y += OffsetY;
+   StopButton[2].y += OffsetY;
+   StopButton[3].y += OffsetY;
+
+   Stop_XL = ds;
+   Stop_XH = Stop_XL + bh;
+   Stop_YL = of + ds;
+   Stop_YH = Stop_YL + bh;
+
+   /* 2. Start Button */
+
+   Start_XL = Stop_XH  + ds;
+   Start_XH = Start_XL + bh;
+   Start_YL = Stop_YL;
+   Start_YH = Stop_YH;
+
+   StartButton[0].y += OffsetY;
+   StartButton[1].y += OffsetY;
+   StartButton[2].y += OffsetY;
+
+   /* 3. Pause Button */
+
+   Pause_XL = Start_XH + 15;
+   Pause_XH = Start_XH + 35;
+   Pause_YL = Start_YL;
+   Pause_YH = Start_YH;
+
+   PauseButton1[0].y += OffsetY;
+   PauseButton1[1].y += OffsetY;
+   PauseButton1[2].y += OffsetY;
+   PauseButton1[3].y += OffsetY;
+
+   PauseButton2[0].y += OffsetY;
+   PauseButton2[1].y += OffsetY;
+   PauseButton2[2].y += OffsetY;
+   PauseButton2[3].y += OffsetY;
+
+   /* 4. Help  Button */
+
+   Help_XL = 200;
+   Help_XH = Help_XL + 5 * fw;
+   Help_YL = Pause_YL;
+   Help_YH = Pause_YH;
+
+   /* 5. Minus & FBWD Button */
+
+   Minus_XL = 300;
+   Minus_XH = Minus_XL + fh;
+   Minus_YL = Pause_YL + (bh - fh) / 2;
+   Minus_YH = Minus_YL + fh;
+
+   FBWD_XH = Minus_XL - ds/2;
+   FBWD_XL = FBWD_XH - fh;
+   FBWD_YL = Minus_YL;
+   FBWD_YH = Minus_YH;
+
+   /* 6. Parameter Change Area */
+
+   Parc_XL = Minus_XH + ds;
+   Parc_XH = Parc_XL  + fw * 14;
+   Parc_YL = Minus_YL;
+   Parc_YH = Minus_YH;
+   Parc_XD = Parc_XH - Parc_XL;
+   Parc_YD = Parc_YH - Parc_YL;
+
+   /* 7. Plus & FFWD Button */
+
+   Plus_XL = Parc_XH + ds;
+   Plus_XH = Plus_XL + fh;
+   Plus_YL = Minus_YL;
+   Plus_YH = Minus_YH;
+
+   FFWD_XL = Plus_XH + ds/2;
+   FFWD_XH = FFWD_XL + fh;
+   FFWD_YL = Plus_YL;
+   FFWD_YH = Plus_YH;
+
+   /* 8. Grid on/off box */
+
+   Grid_XL = Stop_XL;
+   Grid_XH = Grid_XL + FixFontHeight;
+   Grid_YL = Stop_YH + 3 * BigFontHeight / 2;
+   Grid_YH = Grid_YL + FixFontHeight;
+
+   /* Window status and select boxes */
+
+   Wbox_XL = 580;
+   Wbox_XH = Wbox_XL + FixFontHeight;
+   Wbox_YL =   0;
+   Wbox_YH = NumWin  * FixFontHeight;
+}
+
+
+/* Hack for getting information of window decoration  */
+/* especially borderwidth and titleheight             */
+/* These are properties of the window manager and are */
+/* usually adjustable by the user                     */
+
+void TestWindow(int xx, int yy, int wi, int he, int *x, int *y,
+                int *X, int *Y, unsigned int *W, unsigned int *H)
+{
+   unsigned int DepthReturn  = 0;
+   unsigned int BorderReturn = 0;
+   Window TW,Parent,Child;
+   
+   TW = XCreateWindow(display,RootWindow(display,screen_num),
+        xx,yy,wi,he,                   // x,y,w,h
+        0,CopyFromParent,InputOutput,  // border, depth, class
+          CopyFromParent,0,NULL);      // visual, valuemask, attributes
+   XSelectInput(display,TW,ExposureMask);
+   XMapWindow(display,TW);           
+   XMoveWindow(display,TW,xx,yy);
+   XNextEvent(display,&CowEvent);            // Wait until WM mapped it
+   XGetGeometry(display,TW,&Parent,x,y,W,H,&BorderReturn,&DepthReturn);
+   XTranslateCoordinates(display,TW,Parent,0,0,X,Y,&Child);
+   XDestroyWindow(display,TW);
+
+   if (Debug)
+   {
+      printf("TW[%x][%x]: %4d / %4d   %4d x %4d x %2d [%2d:%2d]\n",
+              (int)TW,(int)Parent,*x,*y,*W,*H,DepthReturn,*X,*Y);
+   }
+}
+
+
+void CreateTestWindow(void)
+{
+   int X,Y,xp,yp;
+   unsigned int W,H;
+   
+   // Open a test window with displacement x = 100 and y = 100
+   // Test the returned coordinates for upper left corner
+   // and compute left margin (border) and top margin (title bar)
+
+   TestWindow(100,100,100,100,&xp,&yp,&X,&Y,&W,&H);
+
+   // Left margin
+
+   if (X >= 100 && X < 110) WinLM = X - 100;
+
+   // Right margin
+
+   WinRM = WinLM;
+
+   // Top margin
+
+        if (Y >= 100 && Y < 150) WinTM = Y - 100;
+   else if (Y >    0 && Y <  50) WinTM = Y;
+
+   // Bottom margin
+
+   WinBM = WinLM;
+
+   // Open a full screen test window
+   // Test the returned coordinates for upper left corner
+   // the y displacement should be WinTM plus Windowmanager menu bar
+
+   TestWindow(0,0,ScreenW,ScreenH,&xp,&yp,&X,&Y,&W,&H);
+
+   // Window manager menu bar on top
+
+   if (yp > WinTM) WM_top_area = yp - WinTM;
+
+
+   // Last usable scan line
+
+   ScreenBot = WM_top_area + WinTM + H;
+   if (ScreenBot > ScreenH) ScreenBot = ScreenH;
+
+   // Are we running on a 27" iMac :-)
+
+   if (ScreenW == 2560 && ScreenH > 1400) ScreenBot -= 100;
+
+   if (Debug)
+   {
+      printf("Screen       = %4d x %4d x %2d\n",ScreenW,ScreenH,ScreenD);
+      printf("ScreenBot    = %4d\n",ScreenBot);
+      printf("Top reserved = %4d\n",WM_top_area);
+      printf("Bot reserved = %4d\n",ScreenH-ScreenBot);
+      printf("Left  margin = %4d\n",WinLM);
+      printf("Right margin = %4d\n",WinRM);
+      printf("Top   margin = %4d\n",WinTM);
+      printf("Bot   margin = %4d\n",WinBM);
+   }
+}
+
+
+void TrimCopy(char *Trim, char *Line, int n)
+{
+   int l;
+   char *s;
+
+   l = strlen(Line);
+   Line[--l] = 0;                          // Remove linefeed
+   while (Line[l-1] == ' ') Line[--l] = 0; // Remove trailing blanks
+   s = Line;
+   while (*s == ' ') ++s;                  // Remove leading blanks
+   strncpy(Trim,s,n);
+}
+
+
+int ReadConfig(char *filename)
+{
+   FILE *fp;
+   int i,w,l,s,p;
+   char Line[256];
+   char Plot[80];
+   char Palette[80];
+   char Projection[80];
+   char Rotation[80];
+   char *t;
+
+   fp = fopen(filename,"r");
+   if (!fp) return 1;
+
+   w = -2;
+   s = -1;
+   p = -1;
+   while (!feof(fp))
+   {
+      t = fgets(Line,256,fp);
+      if (Line[0] == '#') continue;
+      if (strncmp(Line,"[Window "    , 8) == 0) w = atoi(Line+8);
+      if (strncmp(Line,"[Control"    , 8) == 0) w = -1;
+      if (strncmp(Line,"[Scalar "    , 8) == 0) s = atoi(Line+8);
+      if (strncmp(Line,"WinRows ="   , 9) == 0)
+      {
+         WinRows = atoi(Line+9);
+         if (WinRows < 1) WinRows = 1;
+         if (WinRows > 3) WinRows = 3;
+         NumWin = WinCols * WinRows;
+      }
+      if (strncmp(Line,"WinCols ="   , 9) == 0)
+      {
+         WinCols = atoi(Line+9);
+         if (WinCols < 1) WinCols = 1;
+         if (WinCols > 3) WinCols = 3;
+         NumWin = WinCols * WinRows;
+      }
+      if (strncmp(Line,"[Parameter " ,11) == 0)
+      {
+         p = atoi(Line+11);
+         if (p >= Parcs) Parcs = p+1;
+      }
+      if (strncmp(Line,"Geometry:",9) == 0 && w >= 0 && w < NUMWIN)
+      {
+         sscanf(Line+9,"%d %d %d %d",&WinAtt[w].w,&WinAtt[w].h,
+			             &WinAtt[w].x,&WinAtt[w].y);
+         WinAtt[w].active = 1;
+      }
+      if (strncmp(Line,"Inactive:",9) == 0 && w >= 0 && w < NUMWIN)
+      {
+         sscanf(Line+9,"%d %d %d %d",&WinAtt[w].w,&WinAtt[w].h,
+			             &WinAtt[w].x,&WinAtt[w].y);
+         WinAtt[w].active = 0;
+      }
+      if (strncmp(Line,"Geometry:",9) == 0 && w == -1)
+      {
+         sscanf(Line+9,"%d %d %d %d",&CowW,&CowH,&CowX,&CowY);
+      }
+      if (strncmp(Line,"Title:",6) == 0 && w >= -1 && w < NUMWIN)
+      {
+         if (w == -1) TrimCopy(PlanetName,Line+6,sizeof(PlanetName)-1);
+         else         TrimCopy(WindowTitle[w]+wto,Line+6,79-wto);
+      }
+      if (strncmp(Line,"Array:",6) == 0 && w >= 0 && w < NUMWIN)
+         TrimCopy(WinAtt[w].array_name,Line+6,79);
+      if (strncmp(Line,"Plot:",5) == 0 && w >= 0 && w < NUMWIN)
+      {
+         TrimCopy(Plot,Line+5,79);
+	 for (i=0 ; i < IsoTypes ; ++i)
+            if (!strcmp(Plot,IsoNames[i])) WinAtt[w].Plot = i;
+      }
+      if (strncmp(Line,"Projection:",11) == 0 && w >= 0 && w < NUMWIN)
+      {
+         TrimCopy(Projection,Line+11,79);
+	 for (i=0 ; i < MAXMAPS ; ++i)
+            if (!strcmp(Projection,ProNames[i])) MapPro[w] = i;
+      }
+      if (strncmp(Line,"Rotation factor:",15) == 0 && w >= 0 && w < NUMWIN)
+      {
+         TrimCopy(Rotation,Line+15,79);
+         MapLR[w].f = atoi(Rotation);
+      }
+      if (strncmp(Line,"Palette:",8) == 0 && w >= 0 && w < NUMWIN)
+      {
+         TrimCopy(Palette,Line+8,79);
+	 for (i=0 ; i < PalTypes ; ++i)
+            if (!strcmp(Palette,PalNames[i])) WinAtt[w].Palette = i;
+      }
+
+      // Dimension for time axis
+
+      if (strncmp(Line,"DimT:" ,5) == 0) DimT = atoi(Line+5);
+
+      // Attributes of scalars for timeseries windows
+
+      if (strncmp(Line,"Name:" ,5) == 0 && s >= 0 && s < NUMSCALARS)
+         TrimCopy(TSName[s],Line+5,79);
+      if (strncmp(Line,"Sub:"  ,4) == 0 && s >= 0 && s < NUMSCALARS)
+         TrimCopy(TSubsc[s],Line+4,79);
+      if (strncmp(Line,"Unit:" ,5) == 0 && s >= 0 && s < NUMSCALARS)
+         TrimCopy(TSUnit[s],Line+5,79);
+      if (strncmp(Line,"Scale:",6) == 0 && s >= 0 && s < NUMSCALARS)
+         TrimCopy(TScale[s],Line+6,79);
+
+      // Attributes of parameter in change menu
+
+      if (strncmp(Line,"ParName:",8) == 0 && p >= 0 && p < PARCS)
+         TrimCopy(Parc[p].Name,Line+8,6);
+      if (strncmp(Line,"ParInc:" ,7) == 0 && p >= 0 && p < PARCS)
+         Parc[p].Inc = atof(Line+7);
+      if (strncmp(Line,"ParMin:" ,7) == 0 && p >= 0 && p < PARCS)
+         Parc[p].Min = atof(Line+7);
+      if (strncmp(Line,"ParMax:" ,7) == 0 && p >= 0 && p < PARCS)
+         Parc[p].Max = atof(Line+7);
+      if (strcmp(Parc[p].Name,"SELLON") == 0) Parc[p].Inc = 360.0 / (2.0 * Latitudes);
+   }
+   fclose(fp);
+   return 0;
+}
+
+
+void CreateControlWindow(void)
+{
+   int X,Y,W,H,B,D,x,y;
+   char Title1[256];
+   char *WinconTitle1;
+   char *WinconTitle3 = {"RUN finished - click on red stop button"};
+   Window Rootwin;
+   Window Child;
+
+   // Create title for control window
+
+   strcpy(Title1,"Unknown model");
+   if (Model == 0) // PUMA
+   {
+      if (MRpid < 0) 
+         strcpy(Title1,"PUMA - KlimaCampus Hamburg");
+      else
+         sprintf(Title1,"Run %d: PUMA - KlimaCampus Hamburg",MRpid);
+   }
+   else if (Model == 1) sprintf(Title1,"SAM - KlimaCampus");
+   else if (Model == 2)
+   {
+       if (MRpid < 0)
+       sprintf(Title1,"Planet Simulator (%s) - KlimaCampus",PlanetName);
+       else
+       sprintf(Title1,"Run %d: Planet Simulator (%s) - KlimaCampus",MRpid,PlanetName);
+   }
+   else if (Model == 3) sprintf(Title1,"Planet Simulator / LSG - KlimaCampus");
+   else if (Model == 4) sprintf(Title1,"CAT - Computer Aided Turbulence");
+   else printf("*** unknown model number %d in guix11 ***\n",Model);
+
+   WinconTitle1 = Title1;
+   if (CowW < 920 || CowW > ScreenW) CowW = 920;
+   if (NumWin < 5) CowH = 6 * FixFontHeight + 5;
+   else            CowH = NumWin * FixFontHeight + 5;
+   if (CowX < 0 || CowX > ScreenW - CowW) CowX = (ScreenW - CowW) / 2;
+   if (CowY < 0 || CowY > ScreenBot - CowH - WinTM - WinBM)
+       CowY = ScreenBot - CowH - WinTM - WinBM;
+   CowSizeHints.flags      = PPosition | PSize | PMinSize | PMaxSize;
+   CowSizeHints.min_width  = CowW;
+   CowSizeHints.min_height = CowH;
+   CowSizeHints.max_width  = ScreenW - WinLM - WinRM;
+   CowSizeHints.max_height = CowH;
+   if (MRnum == 2 && MRpid == 1) CowX += ScreenW;
+   if (Debug) printf("Control Window %d/%d %dx%d\n",CowX,CowY,CowW,CowH);
+   Cow = XCreateWindow(display,RootWindow(display,screen_num), // display, parent
+               CowX,CowY,CowW,CowH,
+               BorderWidth,CopyFromParent,InputOutput,         // border, depth, class
+               CopyFromParent,0,NULL);                         // visual, valuemask, attributes
+   XStringListToTextProperty(&WinconTitle1,1,&WinconName1);
+   XStringListToTextProperty(&WinconTitle3,1,&WinconName3);
+   XStringListToTextProperty(&PauseTitle,1,&WinconPause);
+   XStringListToTextProperty(&ReadyTitle,1,&WinconReady);
+   XSetWMProtocols(display,Cow,&Delwin,1);
+   XSetWMProperties(display,Cow,&WinconName1,NULL,
+		NULL,0,&CowSizeHints,&wm_hints,&class_hints);
+   XSelectInput(display,Cow,ButtonPressMask | KeyPressMask | ExposureMask);
+   XMapWindow(display,Cow);
+}
+
+
+void ShowStep(void)
+{
+   char Text[80];
+   XSetFont(display, gc, BigFont->fid);
+   XSetForeground(display,gc,BlackPix);
+   XSetBackground(display,gc,Grey.pixel);
+
+   if (Model == CAT) // CAT shows timestep
+   {
+      sprintf(Text,"GUI step %9d",ndatim[0]);
+      XDrawImageString(display,Cow,gc,10,BigFontHeight,Text,strlen(Text));
+   }
+   else // PUMA & PLASIM show date and time
+   {
+      ntocdat();
+      if (ndatim[5] == 6) XSetForeground(display,gc,Red.pixel); // sunday
+      XDrawImageString(display,Cow,gc,10,BigFontHeight,datch,strlen(datch));
+      XSetForeground(display,gc,BlackPix);
+   }
+
+   if (ShowQueue)
+   {
+      sprintf(Text,"%8d Events   ",XPending(display));
+      XDrawImageString(display,Cow,gc,10,60 + BigFontHeight,Text,strlen(Text));
+   }
+   else if (fps > 1)
+   {
+      if (SkipFreq < 2) sprintf(Text,"%5d fps",fps);
+      else sprintf(Text,"%5d fps [%d]",fps,SkipFreq);
+      XDrawImageString(display,Cow,gc,10,60 + BigFontHeight,Text,strlen(Text));
+   }
+}
+
+
+int FormatVal(char *Name, float V, char *Text)
+{
+   char Format[80];
+
+   if (V > 9999.9 || V < -999.9)
+   {
+      sprintf(Text,"%6.6s = *****",Name);
+      return strlen(Text);
+   }
+   else if (V > 999.99  ) strcpy(Format,"%6.6s =%6.1f");
+   else if (V >  99.999 ) strcpy(Format,"%6.6s =%6.2f");
+   else if (V >   9.9999) strcpy(Format,"%6.6s =%6.3f");
+   else if (V >   0.0   ) strcpy(Format,"%6.6s =%6.4f");
+   else if (V >  -9.9   ) strcpy(Format,"%6.6s =%6.3f");
+   else if (V > -99.9   ) strcpy(Format,"%6.6s =%6.2f");
+   else                   strcpy(Format,"%6.6s =%6.1f");
+
+   sprintf(Text,Format,Name,V);
+   return strlen(Text);
+}
+
+
+void ShowParcs(void)
+{
+   char Text[80];
+   int len;
+   float V;
+
+   XSetFont(display, gc, BigFont->fid);
+   len = FormatVal(Parc[cpi].Name,Parc[cpi].Val,Text);
+
+   XSetBackground(display,gc,WhitePix);
+   XSetForeground(display,gc,Red.pixel);
+   XFillRectangle(display,Cow,gc,Minus_XL,Minus_YL,Minus_XH-Minus_XL,Minus_YH-Minus_YL);
+   XFillRectangle(display,Cow,gc,FBWD_XL,FBWD_YL,FBWD_XH-FBWD_XL,FBWD_YH-FBWD_YL);
+   XSetForeground(display,gc,WhitePix);
+   XFillRectangle(display,Cow,gc,Minus_XL+3,(Minus_YH+Minus_YL)/2-1,Minus_XH-Minus_XL-5,3);
+   XFillRectangle(display,Cow,gc,FBWD_XL+3,(FBWD_YH+FBWD_YL)/2-1,FBWD_XH-FBWD_XL-5,3);
+   XSetForeground(display,gc,BlackPix);
+   XDrawImageString(display,Cow,gc,Parc_XL,Parc_YH-3,Text,len);
+   XSetForeground(display,gc,Green.pixel);
+   XFillRectangle(display,Cow,gc,Plus_XL,Plus_YL,Plus_XH-Plus_XL,Plus_YH-Plus_YL);
+   XFillRectangle(display,Cow,gc,FFWD_XL,FFWD_YL,FFWD_XH-FFWD_XL,FFWD_YH-FFWD_YL);
+   XSetForeground(display,gc,WhitePix);
+   XFillRectangle(display,Cow,gc,Plus_XL+3,(Plus_YH+Plus_YL)/2-1,Plus_XH-Plus_XL-5,3);
+   XFillRectangle(display,Cow,gc,FFWD_XL+3,(FFWD_YH+FFWD_YL)/2-1,FFWD_XH-FFWD_XL-5,3);
+   XFillRectangle(display,Cow,gc,(Plus_XH+Plus_XL)/2-1,Plus_YL+3,3,Plus_YH-Plus_YL-5);
+   XFillRectangle(display,Cow,gc,(FFWD_XH+FFWD_XL)/2-1,FFWD_YL+3,3,FFWD_YH-FFWD_YL-5);
+   XSetForeground(display,gc,BlackPix);
+   XDrawRectangle(display,Cow,gc,Minus_XL,Minus_YL,Minus_XH-Minus_XL,Minus_YH-Minus_YL);
+   XDrawRectangle(display,Cow,gc,FBWD_XL,FBWD_YL,FBWD_XH-FBWD_XL,FBWD_YH-FBWD_YL);
+   XDrawRectangle(display,Cow,gc,Parc_XL-1,Parc_YL-1,Parc_XH-Parc_XL+1,Parc_YH-Parc_YL);
+   XDrawRectangle(display,Cow,gc,Plus_XL,Plus_YL,Plus_XH-Plus_XL,Plus_YH-Plus_YL);
+   XDrawRectangle(display,Cow,gc,FFWD_XL,FFWD_YL,FFWD_XH-FFWD_XL,FFWD_YH-FFWD_YL);
+
+   /* Show next parameter */
+
+   strcpy(Text,"              ");
+   if (cpi < Parcs-1) FormatVal(Parc[cpi+1].Name,Parc[cpi+1].Val,Text);
+   len = strlen(Text);
+
+   XSetBackground(display,gc,WhitePix);
+   XSetForeground(display,gc,BlackPix);
+   XDrawImageString(display,Cow,gc,Parc_XL,2*Parc_YH-Parc_YL-3,Text,len);
+   XDrawRectangle(display,Cow,gc,Parc_XL-1,Parc_YH-1,Parc_XH-Parc_XL+1,Parc_YH-Parc_YL);
+
+   /* Show previous parameter */
+
+   strcpy(Text,"              ");
+   if (cpi > 0) FormatVal(Parc[cpi-1].Name,Parc[cpi-1].Val,Text);
+   len = strlen(Text);
+
+   XSetBackground(display,gc,WhitePix);
+   XSetForeground(display,gc,BlackPix);
+   XDrawImageString(display,Cow,gc,Parc_XL,Parc_YL-3,Text,len);
+   XDrawRectangle(display,Cow,gc,Parc_XL-1,2*Parc_YL-Parc_YH-1,Parc_XH-Parc_XL+1,Parc_YH-Parc_YL);
+   XSetFont(display, gc, FixFont->fid);
+
+}
+
+
+void CheckMark(int x, int y, int d)
+{
+   XDrawLine(display,Cow,gc,x+2,y+2,x+d-1,y+d-1);
+   XDrawLine(display,Cow,gc,x+3,y+2,x+d-1,y+d-2);
+   XDrawLine(display,Cow,gc,x+2,y+3,x+d-2,y+d-1);
+
+   XDrawLine(display,Cow,gc,x+d-1,y+1,x+2,y+d-2);
+   XDrawLine(display,Cow,gc,x+d-2,y+1,x+2,y+d-3);
+   XDrawLine(display,Cow,gc,x+d-1,y+2,x+3,y+d-2);
+}
+
+
+void ShowWindowStatus(void)
+{
+   char *cp;
+   char Text[80];
+   int len,w,x,d;
+
+   XSetFont(display, gc, FixFont->fid);
+   XSetForeground(display,gc,BlackPix);
+   XSetBackground(display,gc,Grey.pixel);
+   x = Wbox_XL;
+   d = FixFontHeight;
+   for (w=0 ; w < NumWin ; ++w)
+   {
+      strncpy(Text,WindowTitle[w]+wto,40);
+      Text[40] = 0;
+      cp = strstr(Text,"Level");
+      if (cp) *cp = 0;
+      cp = strstr(Text,"Latitude");
+      if (cp) *cp = 0;
+      len = strlen(Text);
+      XDrawImageString(display,Cow,gc,x+20,(w+1) * d,Text,len);
+   }
+   XSetForeground(display,gc,WhitePix);
+   for (w=0 ; w < NumWin ; ++w)
+   {
+      XFillRectangle(display,Cow,gc,x,w*d,d,d);
+   }
+   XSetForeground(display,gc,BlackPix);
+   for (w=0 ; w < NumWin ; ++w)
+   {
+      XDrawRectangle(display,Cow,gc,x,w*d,d,d);
+   }
+   for (w=0 ; w < NumWin ; ++w)
+   if (Win[w]) CheckMark(x,w*d,d);
+}
+
+
+void ShowGridStatus(void)
+{
+   int x,y,d;
+
+   d = FixFontHeight;
+   x = Grid_XL;
+   y = Grid_YL;
+   XSetFont(display, gc, FixFont->fid);
+   XSetForeground(display,gc,BlackPix);
+   XSetBackground(display,gc,Grey.pixel);
+   XDrawImageString(display,Cow,gc,Grid_XH+FixFontWidth,Grid_YH,"Grid",4);
+   XSetForeground(display,gc,WhitePix);
+   XFillRectangle(display,Cow,gc,x,Grid_YL,d,d);
+   XSetForeground(display,gc,BlackPix);
+   XDrawRectangle(display,Cow,gc,x,Grid_YL,d,d);
+
+   if (Grid) CheckMark(x,y,d);
+}
+
+      
+int RedrawControlWindow(void)
+{
+   char Text[80];
+   int status,WinXSize,WinYSize,font_height,width,len;
+   int i,j,x1,x2,y1,y2,y3;
+   XWindowAttributes CurAtt;
+
+   status = XGetWindowAttributes(display,Cow,&CurAtt);
+   WinXSize = CurAtt.width;
+   WinYSize = CurAtt.height;
+   
+   XSetForeground(display,gc,BlackPix);
+   XSetBackground(display,gc,WhitePix);
+
+   XSetWindowBackground(display,Cow,Grey.pixel);
+   XClearWindow(display,Cow);
+
+   /* Red stop button */
+
+   XSetForeground(display,gc,Red.pixel);
+   XFillPolygon(display,Cow,gc,StopButton,4,Convex,CoordModeOrigin);
+   XSetForeground(display,gc,WhitePix);
+   x1 = StopButton[0].x ;
+   y1 = StopButton[0].y ;
+   for (j=0 ; j < PSDIM ; ++j)
+   for (i=0 ; i < PSDIM ; ++i)
+   if (pixelstar[j][i] == '*')
+      XDrawPoint(display,Cow,gc,i+x1,j+y1);
+  
+   XSetForeground(display,gc,LightRed.pixel);
+   x1 = 10; x2 = 40 ; y1 = OffsetY + 10 ; y2 = OffsetY + 40;
+   XDrawLine(display,Cow,gc,x2  ,y1-1,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x2+1,y1-2,x2+1,y2+1);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x2  ,y1-1);
+   XDrawLine(display,Cow,gc,x2+1,y2-2,x2+1,y1-2);
+   XSetForeground(display,gc,DarkRed.pixel);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x1-1,y2  );
+   XDrawLine(display,Cow,gc,x1-2,y1-2,x1-2,y2+1);
+   XDrawLine(display,Cow,gc,x1-1,y2  ,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x1-2,y2+1,x2+1,y2+1);
+
+   // Green <play> button
+
+   XSetForeground(display,gc,Green.pixel);
+   XFillPolygon(display,Cow,gc,StartButton,3,Convex,CoordModeOrigin);
+   x1 = 50; x2 = 80 ; y1 = OffsetY + 10 ; y2 = OffsetY + 25; y3 = OffsetY + 40;
+   XSetForeground(display,gc,LightGreen.pixel);
+   XDrawLine(display,Cow,gc,x1  ,y1-1,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x1  ,y1-2,x2+1,y2  );
+   XSetForeground(display,gc,DarkGreen.pixel);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x1-1,y3+1);
+   XDrawLine(display,Cow,gc,x1-2,y1-2,x1-2,y3+2);
+
+   // Blue <pause> button
+
+   XSetForeground(display,gc,Blue.pixel);
+   XFillPolygon(display,Cow,gc,PauseButton1,4,Convex,CoordModeOrigin);
+   XFillPolygon(display,Cow,gc,PauseButton2,4,Convex,CoordModeOrigin);
+   
+   x1 = 95; x2 = 102; y1 = OffsetY + 10; y2 = OffsetY + 40;
+   XSetForeground(display,gc,DarkBlue.pixel);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x1-1,y2  );
+   XDrawLine(display,Cow,gc,x1-2,y1-2,x1-2,y2+1);
+   XDrawLine(display,Cow,gc,x1-1,y2  ,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x1-2,y2+1,x2+1,y2+1);
+   XSetForeground(display,gc,LightBlue.pixel);
+   XDrawLine(display,Cow,gc,x2  ,y1-1,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x2+1,y1-2,x2+1,y2+1);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x2  ,y1-1);
+   XDrawLine(display,Cow,gc,x2+1,y2-2,x2+1,y1-2);
+
+   x1 = 108; x2 = 115; y1 = OffsetY + 10; y2 = OffsetY + 40;
+   XSetForeground(display,gc,DarkBlue.pixel);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x1-1,y2  );
+   XDrawLine(display,Cow,gc,x1-2,y1-2,x1-2,y2+1);
+   XDrawLine(display,Cow,gc,x1-1,y2  ,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x1-2,y2+1,x2+1,y2+1);
+   XSetForeground(display,gc,LightBlue.pixel);
+   XDrawLine(display,Cow,gc,x2  ,y1-1,x2  ,y2  );
+   XDrawLine(display,Cow,gc,x2+1,y1-2,x2+1,y2+1);
+   XDrawLine(display,Cow,gc,x1-1,y1-1,x2  ,y1-1);
+   XDrawLine(display,Cow,gc,x2+1,y2-2,x2+1,y1-2);
+
+   // Help button
+
+   x1 = 200; x2 = x1 + 5 * BigFontWidth; y1 = OffsetY + 10; y2 = y1 + 30;
+   XSetForeground(display,gc,Red.pixel);
+   XFillRectangle(display,Cow,gc,x1,y1,x2-x1,y2-y1);
+   XSetForeground(display,gc,BlackPix);
+   XDrawRectangle(display,Cow,gc,x1-1,y1-1,x2-x1+1,y2-y1+1);
+   XSetFont(display,gc,BigFont->fid);
+   XSetForeground(display,gc,Yellow.pixel);
+   XSetBackground(display,gc,Red.pixel);
+   XDrawImageString(display,Cow,gc,x1+BigFontWidth/2,(y1+y2)/2+BigFont->ascent/2,"HELP",4);
+
+   ShowStep();
+   ShowParcs();
+   ShowWindowStatus();
+   ShowGridStatus();
+   return 0;
+}
+
+
+void ClearTracer(void)
+{
+   int j;
+   for (j=0 ; j < MAXPAR ; ++j)
+   {
+      pax[j] = -1.0;
+      pay[j] = -1.0;
+   }
+}
+
+
+int CheckEndianess(void)
+{
+   union EndianCheck
+   {
+      char b[sizeof(int)];
+      int  i;
+   } ec;
+
+   ec.i = 8; 
+   return (ec.b[0] == 0);
+}
+
+
+void initgui_(int *model, int *debug, int *lats, int *mrpid, int *mrnum, char *plan)
+{
+   int x,y,w,h;
+   int argc = 1;
+   int i,j;
+   unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
+   XGCValues values;
+   XEvent Event;
+   struct timeval TimeVal;
+
+   // Check for big endian computer
+   // The bitmap format ".bmp" ist little endian
+
+   BigEndian = CheckEndianess();
+
+   // Set seed for random number generator from clock
+
+   gettimeofday(&TimeVal,NULL);
+   Seed = TimeVal.tv_sec;
+   
+   Model = *model;
+   Debug = *debug;
+   Latitudes = *lats;
+   MRpid = *mrpid;
+   MRnum = *mrnum;
+   strncpy(PlanetName,plan,sizeof(PlanetName)-1);
+
+   if (MRpid >= 0)
+   {
+      sprintf(wtrun,"[%d] ",MRpid);
+      wto = strlen(wtrun);
+   }
+
+   if (Debug) printf("initgui(%d,%d)\n",Model,Debug);
+   if ((display=XOpenDisplay(display_name)) == NULL)
+   {
+      fprintf(stderr,"%s: cannot connect to X server %s\n", 
+              progname, XDisplayName(display_name));
+      exit(1);
+   }
+   screen_num = DefaultScreen(display);
+   ScreenD  = XDefaultDepth(display,screen_num);
+   ScreenW  = DisplayWidth (display,screen_num);
+   ScreenH  = DisplayHeight(display,screen_num);
+   BlackPix = BlackPixel(display,screen_num);
+   WhitePix = WhitePixel(display,screen_num);
+   SmallScreen = ScreenH <= 768;
+   if (SmallScreen)
+   {
+      WinRows = 2;
+      NumWin  = WinCols * WinRows;
+      Grid = 0;
+   }
+
+   if (MRnum == 2) ScreenW /= 2; /* Run with two GUI's */
+
+   /* Fix defaults for multihead displays */
+
+   if (ScreenH > ScreenW && ScreenH > 1200) ScreenH = 1200;
+   if (ScreenW > 2 * ScreenH && ScreenW >= 2048) ScreenW /= 2;
+
+   for (i = 0 ; i < NUMWIN ; ++i)
+   {
+      WindowTitle[i] = CharAlloc(256,"WindowTitle");
+      if (wto == 0) sprintf(WindowTitle[i],"Window %d",i+1);
+      else          sprintf(WindowTitle[i],"%sWindow %d",wtrun,i+1);
+      WinAtt[i].x = -1;
+      WinAtt[i].y = -1;
+      WinAtt[i].w = -1;
+      WinAtt[i].h = -1;
+      WinAtt[i].active = 1;
+   }
+
+   CreateTestWindow();
+
+   if (MRpid >= 0) sprintf(GUI_default,"GUI_%2.2d.cfg",MRpid);
+   ReadConfig(GUI_default);
+   if (MRpid >= 0) sprintf(GUI_config,"GUI_last_used_%2.2d.cfg",MRpid);
+   ReadConfig(GUI_config);
+
+   LoadFonts();
+   CreateControlWindow();
+
+   OutXSize = (ScreenW-ScreenOffset) / WinCols;
+   OutYSize = (CowY-ScreenOffset-1-WM_top_area)  / WinRows;
+   WinXSize = OutXSize - WinLM - WinRM;
+   WinYSize = OutYSize - WinTM - WinBM;
+   WinSizeHints.flags      = PPosition | PSize | PMinSize;
+   WinSizeHints.min_width  = 200;
+   WinSizeHints.min_height = 100;
+   if (Debug)
+   {
+      printf("Outer windowsize = %dx%d\n",OutXSize,OutYSize);
+      printf("Inner windowsize = %dx%d\n",WinXSize,WinYSize);
+   }
+
+   wm_hints.initial_state = NormalState;
+   wm_hints.input = True;
+   wm_hints.flags = StateHint | InputHint;
+   
+   class_hints.res_name = progname;
+   class_hints.res_class = "PUMA";
+
+   Delwin = XInternAtom(display,"WM_DELETE_WINDOW",0);
+
+   ReadImage(&MapHR,"map.bmp");
+
+   for (i = 0 ; i < NumWin ; ++i)
+   {
+      x = WinAtt[i].x;
+      y = WinAtt[i].y;
+      w = WinAtt[i].w;
+      h = WinAtt[i].h;
+
+      if (x < ScreenOffset || x >= ScreenW) x = ScreenOffset+(i%WinCols)*OutXSize;
+      if (y < ScreenOffset || y >= ScreenH) y = ScreenOffset+(i/WinCols)*OutYSize+WM_top_area;
+      if (w <  WinSizeHints.min_width ) w = WinXSize;
+      if (h <  WinSizeHints.min_height) h = WinYSize;
+      XStringListToTextProperty(&WindowTitle[i],1,WindowName+i);
+      if (WinAtt[i].active)
+      {
+         if (MRnum == 2 && MRpid == 1) x += ScreenW;
+         Win[i] = XCreateWindow(display,RootWindow(display,screen_num), // display, parent
+                  x,y,w,h,
+                  BorderWidth,CopyFromParent,InputOutput,         // border, depth, class
+                  CopyFromParent,0,NULL);                         // visual, valuemask, attributes
+         XSetWMProtocols(display,Win[i],&Delwin,1);
+         XSetWMProperties(display,Win[i],WindowName+i,NULL,
+   		NULL,0,&WinSizeHints,&wm_hints,&class_hints);
+         XSelectInput(display,Win[i],ButtonPressMask | KeyPressMask | ExposureMask);
+         XMapWindow(display,Win[i]);
+      }
+   }
+
+   /* Prepare GC */
+
+   gc = XCreateGC(display, Cow, valuemask, &values);
+   XSetFont(display, gc, FixFont->fid);
+   colormap = XDefaultColormap(display,screen_num);
+   XSetForeground(display,gc,BlackPix);
+   XSetBackground(display,gc,WhitePix);
+
+   /* Get keyboard information */
+
+   XDisplayKeycodes(display,&FirstKey,&LastKey);
+   KeyMap = XGetKeyboardMapping(display,FirstKey,LastKey-FirstKey+1,&SymsPerKey);
+
+   /* Allocate color cells */
+
+   for (i=0 ; i < NUMPAL ; ++i)
+      LineCo[i] = AllocateColorCells(Pallet[i]);
+  
+   /* Color cells for control window */
+
+   XAllocNamedColor(display,colormap,"red"        ,&Red       ,&Dummy);
+   XAllocNamedColor(display,colormap,"green"      ,&Green     ,&Dummy);
+   XAllocNamedColor(display,colormap,"blue"       ,&Blue      ,&Dummy);
+   XAllocNamedColor(display,colormap,"grey"       ,&Grey      ,&Dummy);
+   XAllocNamedColor(display,colormap,"yellow"     ,&Yellow    ,&Dummy);
+   XAllocNamedColor(display,colormap,"hot pink"   ,&LightRed  ,&Dummy);
+   XAllocNamedColor(display,colormap,"dark red"   ,&DarkRed   ,&Dummy);
+   XAllocNamedColor(display,colormap,"light blue" ,&LightBlue ,&Dummy);
+   XAllocNamedColor(display,colormap,"dark blue"  ,&DarkBlue  ,&Dummy);
+   XAllocNamedColor(display,colormap,"light green",&LightGreen,&Dummy);
+   XAllocNamedColor(display,colormap,"dark green" ,&DarkGreen ,&Dummy);
+
+   TSColor[0] = Red.pixel;
+   TSColor[1] = Green.pixel;
+   TSColor[2] = Blue.pixel;
+   TSColor[3] = WhitePix;
+   TSColor[4] = LightRed.pixel;
+   TSColor[5] = Grey.pixel;
+   TSColor[6] = Yellow.pixel;
+   TSColor[7] = LightBlue.pixel;
+   TSColor[8] = LightGreen.pixel;
+
+   ClearTracer();
+   CalcButtonAreas();
+   RedrawControlWindow();
+   XSync(display,0);
+}
+
+void FillPoly(int n, REAL Poly[])
+{
+   int i;
+   XPoint xpol[8];
+   for (i=0; i < n ; ++i)
+   {
+      xpol[i].x = OffX + Poly[i+i  ] + 0.5;
+      xpol[i].y = OffY + Poly[i+i+1] + 0.5;
+   }
+   XFillPolygon(display,pix,gc,xpol,n,Convex,CoordModeOrigin);
+}
+
+/* ======= */
+/* IsoArea */
+/* ======= */
+
+void IsoArea(INT y, REAL vl, REAL vh, REAL Top[], REAL Bot[], INT Dim)
+{
+   INT  f,x,p;
+   REAL xl,xr,yt,yb;
+   REAL Poly[16];
+
+   // if (Debug) printf("IsoArea %d %10.2f %10.2f %10.2f %10.2f %d\n",y,vl,vh,Top[0],Bot[0],Dim);
+   for (x=0 ; x < Dim-1 ; x++)
+   {
+      Flag[x] = 0;
+      if (Top[x  ] <  vl) Flag[x] |= TOLELO;
+      if (Top[x  ] >= vh) Flag[x] |= TOLEHI;
+      if (Top[x+1] <  vl) Flag[x] |= TORILO;
+      if (Top[x+1] >= vh) Flag[x] |= TORIHI;
+      if (Bot[x  ] <  vl) Flag[x] |= BOLELO;
+      if (Bot[x  ] >= vh) Flag[x] |= BOLEHI;
+      if (Bot[x+1] <  vl) Flag[x] |= BORILO;
+      if (Bot[x+1] >= vh) Flag[x] |= BORIHI;
+   }
+
+   x = 0;
+
+   while (x < Dim-1)
+   {
+      xl = VGAX *  x   ;
+      xr = VGAX * (x+1);
+      yt = VGAY *  y   ;
+      yb = VGAY * (y+1);
+      f  = Flag[x];
+
+      if (f == 0)
+      {
+	 x++;
+	 while (x < Dim-1 && Flag[x] == 0)
+	 {
+	    x++;
+	    xr = VGAX * x;
+	 }
+	 Poly[0] = Poly[6] = xl;
+	 Poly[1] = Poly[3] = yt;
+	 Poly[2] = Poly[4] = xr;
+	 Poly[5] = Poly[7] = yb;
+
+	 FillPoly(4,Poly);
+
+      }
+      else if (f == (TOLELO | TORILO | BOLELO | BORILO) ||
+	       f == (TOLEHI | TORIHI | BOLEHI | BORIHI))   x++;
+      else if (Top[x] < vl && Top[x+1] >= vl && Bot[x] >= vl && Bot[x+1] < vl)
+      {
+	 Poly[1] = Poly[3] = yt;
+	 Poly[2] = Poly[4] = xr;
+         Poly[0] = IPX(Top[x  ],vl,Top[x+1]);
+         Poly[5] = IPY(Top[x+1],vl,Bot[x+1]);
+         FillPoly(3,Poly);
+         Poly[1] = Poly[3] = yb;
+         Poly[2] = Poly[4] = xl;
+         Poly[0] = IPX(Bot[x  ],vl,Bot[x+1]);
+         Poly[5] = IPY(Top[x  ],vl,Bot[x  ]);
+         FillPoly(3,Poly);
+         ++x;
+      }
+      else if (Top[x] >= vl && Top[x+1] < vl && Bot[x] < vl && Bot[x+1] >= vl)
+      {
+	 Poly[0] = Poly[4] = xl;
+	 Poly[1] = Poly[3] = yt;
+         Poly[2] = IPX(Top[x  ],vl,Top[x+1]);
+         Poly[5] = IPY(Top[x  ],vl,Bot[x  ]);
+         FillPoly(3,Poly);
+         Poly[0] = Poly[2] = xr;
+         Poly[3] = Poly[5] = yb;
+         Poly[1] = IPY(Top[x+1],vl,Bot[x+1]);
+         Poly[4] = IPX(Bot[x  ],vl,Bot[x+1]);
+         FillPoly(3,Poly);
+         ++x;
+      }
+      else
+      {
+	 p = 0;
+
+	 if (Top[x] < vl)
+	 {
+	    if (Top[x+1] >= vl)
+	    {
+	       Poly[p++] = IPX(Top[x],vl,Top[x+1]);
+	       Poly[p++] = yt;
+	    }
+
+	    if (Top[x+1] >= vh)
+	    {
+	       Poly[p++] = IPX(Top[x],vh,Top[x+1]);
+	       Poly[p++] = yt;
+	    }
+	 }
+	 else if (Top[x] >= vh)
+	 {
+	    if (Top[x+1] < vh)
+	    {
+	       Poly[p++] = IPX(Top[x],vh,Top[x+1]);
+	       Poly[p++] = yt;
+	    }
+	    if (Top[x+1] < vl)
+	    {
+	       Poly[p++] = IPX(Top[x],vl,Top[x+1]);
+	       Poly[p++] = yt;
+	    }
+	 }
+	 else
+	 {
+	    Poly[p++] = xl;
+	    Poly[p++] = yt;
+	    if (Top[x+1] < vl)
+	    {
+	       Poly[p++] = IPX(Top[x],vl,Top[x+1]);
+	       Poly[p++] = yt;
+	    }
+	    if (Top[x+1] >= vh)
+	    {
+	       Poly[p++] = IPX(Top[x],vh,Top[x+1]);
+	       Poly[p++] = yt;
+	    }
+	 }
+
+	 if (Top[x+1] < vl)
+	 {
+	    if (Bot[x+1] >= vl)
+	    {
+	       Poly[p++] = xr;
+	       Poly[p++] = IPY(Top[x+1],vl,Bot[x+1]);
+	    }
+
+	    if (Bot[x+1] >= vh)
+	    {
+	       Poly[p++] = xr;
+	       Poly[p++] = IPY(Top[x+1],vh,Bot[x+1]);
+	    }
+	 }
+	 else if (Top[x+1] >= vh)
+	 {
+	    if (Bot[x+1] < vh)
+	    {
+	       Poly[p++] = xr;
+	       Poly[p++] = IPY(Top[x+1],vh,Bot[x+1]);
+	    }
+	    if (Bot[x+1] < vl)
+	    {
+	       Poly[p++] = xr;
+	       Poly[p++] = IPY(Top[x+1],vl,Bot[x+1]);
+	    }
+	 }
+	 else
+	 {
+	    Poly[p++] = xr;
+	    Poly[p++] = yt;
+	    if (Bot[x+1] < vl)
+	    {
+	       Poly[p++] = xr;
+	       Poly[p++] = IPY(Top[x+1],vl,Bot[x+1]);
+	    }
+	    if (Bot[x+1] >= vh)
+	    {
+	       Poly[p++] = xr;
+	       Poly[p++] = IPY(Top[x+1],vh,Bot[x+1]);
+	    }
+	 }
+
+	 if (Bot[x+1] < vl)
+	 {
+	    if (Bot[x] >= vl)
+	    {
+	       Poly[p++] = IPX(Bot[x],vl,Bot[x+1]);
+	       Poly[p++] = yb;
+	    }
+	    if (Bot[x] >= vh)
+	    {
+	       Poly[p++] = IPX(Bot[x],vh,Bot[x+1]);
+	       Poly[p++] = yb;
+	    }
+	 }
+	 else if (Bot[x+1] >= vh)
+	 {
+	    if (Bot[x] < vh)
+	    {
+	       Poly[p++] = IPX(Bot[x],vh,Bot[x+1]);
+	       Poly[p++] = yb;
+	    }
+	    if (Bot[x] < vl)
+	    {
+	       Poly[p++] = IPX(Bot[x],vl,Bot[x+1]);
+	       Poly[p++] = yb;
+	    }
+	 }
+	 else
+	 {
+	    Poly[p++] = xr;
+	    Poly[p++] = yb;
+	    if (Bot[x] < vl)
+	    {
+	       Poly[p++] = IPX(Bot[x],vl,Bot[x+1]);
+	       Poly[p++] = yb;
+	    }
+	    if (Bot[x] >= vh)
+	    {
+	       Poly[p++] = IPX(Bot[x],vh,Bot[x+1]);
+	       Poly[p++] = yb;
+	    }
+	 }
+
+	 if (Bot[x] < vl)
+	 {
+	    if (Top[x] >= vl)
+	    {
+	       Poly[p++] = xl;
+	       Poly[p++] = IPY(Top[x],vl,Bot[x]);
+	    }
+
+	    if (Top[x] >= vh)
+	    {
+	       Poly[p++] = xl;
+	       Poly[p++] = IPY(Top[x],vh,Bot[x]);
+	    }
+	 }
+	 else if (Bot[x] >= vh)
+	 {
+	    if (Top[x] < vh)
+	    {
+	       Poly[p++] = xl;
+	       Poly[p++] = IPY(Top[x],vh,Bot[x]);
+	    }
+	    if (Top[x] < vl)
+	    {
+	       Poly[p++] = xl;
+	       Poly[p++] = IPY(Top[x],vl,Bot[x]);
+	    }
+	 }
+	 else
+	 {
+	    Poly[p++] = xl;
+	    Poly[p++] = yb;
+	    if (Top[x] < vl)
+	    {
+	       Poly[p++] = xl;
+	       Poly[p++] = IPY(Top[x],vl,Bot[x]);
+	    }
+	    if (Top[x] >= vh)
+	    {
+	       Poly[p++] = xl;
+	       Poly[p++] = IPY(Top[x],vh,Bot[x]);
+	    }
+	 }
+	 FillPoly(p>>1,Poly);
+	 x++;
+      }
+   }
+}
+
+
+/* ======= */
+/* isoarea */
+/* ======= */
+
+void IsoAreas(struct ColorStrip Strip[])
+{
+   INT  i;
+   INT  y;
+   REAL *Top;
+   REAL *Bot;
+
+   i = 0;
+   while (Strip[i].Name)
+   {
+      Top = Field;
+      Bot = Field + DimX;
+      XSetForeground(display,gc,Strip[i].pixel);
+      for (y = 0 ; y < DimY-1 ; y++)
+      {
+	 IsoArea(y,Strip[i].Lo,Strip[i].Hi,Top,Bot,DimX);
+	 Top += DimX;
+	 Bot += DimX;
+      }
+      ++i;
+   }
+}
+
+/* ======= */
+/* IsoLine */
+/* ======= */
+
+void IsoLine(INT y, REAL v, REAL Top[], REAL Bot[], INT Dim)
+{
+   INT  f,x;
+   REAL xl,xr,yt,yb;
+   REAL x1,yo,x2,y2,x3,y3,x4,y4;
+
+   for (x=0 ; x < Dim-1 ; x++)
+   {
+      Flag[x] = 0;
+      if (Top[x  ] <  v) Flag[x] |= TOLELO;
+      else               Flag[x] |= TOLEHI;
+      if (Top[x+1] <  v) Flag[x] |= TORILO;
+      else               Flag[x] |= TORIHI;
+      if (Bot[x  ] <  v) Flag[x] |= BOLELO;
+      else               Flag[x] |= BOLEHI;
+      if (Bot[x+1] <  v) Flag[x] |= BORILO;
+      else               Flag[x] |= BORIHI;
+   }
+
+   x = 0;
+
+   while (x < Dim-1)
+   {
+      xl = VGAX *  x   ;
+      xr = VGAX * (x+1);
+      yt = VGAY *  y   ;
+      yb = VGAY * (y+1);
+      f  = Flag[x];
+
+      if (f == 0 || f == (TOLELO | TORILO | BOLELO | BORILO) ||
+		    f == (TOLEHI | TORIHI | BOLEHI | BORIHI))   x++;
+      else if (f == (TOLELO | BORILO | TORIHI | BOLEHI))
+      {
+         x1 = IPX(Top[x  ],v,Top[x+1]);
+         yo = yt;
+         x2 = xr;
+         y2 = IPY(Top[x+1],v,Bot[x+1]);
+         x3 = IPX(Bot[x  ],v,Bot[x+1]);
+         y3 = yb;
+         x4 = xl;
+         y4 = IPY(Top[x  ],v,Bot[x  ]);
+	 XDrawLine(display,pix,gc,x1,OffY+yo,x2,OffY+y2);
+	 XDrawLine(display,pix,gc,x3,OffY+y3,x4,OffY+y4);
+         ++x;
+      }
+      else if (f == (TORILO | BOLELO | TOLEHI | BORIHI))
+      {
+         x1 = xl;
+         yo = IPY(Top[x  ],v,Bot[x  ]);
+         x2 = IPX(Top[x  ],v,Top[x+1]);
+         y2 = yt;
+         x3 = xr;
+         y3 = IPY(Top[x+1],v,Bot[x+1]);
+         x4 = IPX(Bot[x  ],v,Bot[x+1]);
+         y4 = yb;
+	 XDrawLine(display,pix,gc,x1,OffY+yo,x2,OffY+y2);
+	 XDrawLine(display,pix,gc,x3,OffY+y3,x4,OffY+y4);
+         ++x;
+      }
+      else
+      {
+	 x1 = x2 = x3 = x4 = -1;
+
+	 if ((Top[x  ] < v && Top[x+1] >= v) || (Top[x  ] >= v && Top[x+1] < v))
+	 {
+	    x1 = IPX(Top[x  ],v,Top[x+1]);
+	    yo = yt;
+	 }
+	 if ((Top[x+1] < v && Bot[x+1] >= v) || (Top[x+1] >= v && Bot[x+1] < v))
+	 {
+	    x2 = xr;
+	    y2 = IPY(Top[x+1],v,Bot[x+1]);
+	 }
+	 if ((Bot[x+1] < v && Bot[x  ] >= v) || (Bot[x+1] >= v && Bot[x  ] < v))
+	 {
+	    x3 = IPX(Bot[x  ],v,Bot[x+1]);
+	    y3 = yb;
+	 }
+	 if ((Bot[x  ] < v && Top[x  ] >= v) || (Bot[x  ] >= v && Top[x  ] < v))
+	 {
+	    x4 = xl;
+	    y4 = IPY(Top[x  ],v,Bot[x  ]);
+	 }
+
+	 if (x1 >= 0 && x2 >= 0 && x3 >= 0 && x4 >= 0)
+	 {
+	    XDrawLine(display,pix,gc,x1,OffY+yo,x2,OffY+y2);
+	    XDrawLine(display,pix,gc,x3,OffY+y3,x4,OffY+y4);
+	 }
+	 else if (x1 >= 0)
+	 {
+	    if      (x2 >= 0) XDrawLine(display,pix,gc,x1,OffY+yo,x2,OffY+y2);
+	    else if (x3 >= 0) XDrawLine(display,pix,gc,x1,OffY+yo,x3,OffY+y3);
+	    else              XDrawLine(display,pix,gc,x1,OffY+yo,x4,OffY+y4);
+	 }
+	 else if (x2 >= 0)
+	 {
+	    if (x3 >= 0) XDrawLine(display,pix,gc,x2,OffY+y2,x3,OffY+y3);
+	    else         XDrawLine(display,pix,gc,x2,OffY+y2,x4,OffY+y4);
+	 }
+	 else XDrawLine(display,pix,gc,x3,OffY+y3,x4,OffY+y4);
+
+	 x++;
+      }
+   }
+}
+
+
+/* ======== */
+/* IsoLines */
+/* ======== */
+
+void IsoLines(struct ColorStrip Strip[],int Colored)
+{
+   INT  i;
+   INT  y;
+   REAL *Top;
+   REAL *Bot;
+
+   XSetForeground(display,gc,BlackPix);
+   i = 0;
+   while (Strip[i].Name)
+   {
+      Top = Field;
+      Bot = Field + DimX;
+      if (Colored) XSetForeground(display,gc,Strip[i].pixel);
+      for (y = 0 ; y < DimY-1 ; y++)
+      {
+	 IsoLine(y,Strip[i].Lo,Top,Bot,DimX);
+	 Top += DimX;
+	 Bot += DimX;
+      }
+      ++i;
+   }
+}
+
+int AziPoint(int fpx, int fpy, int *x2, int *y2)
+{
+   int xc,yc;
+   double flam,fsin,fcos,roa,pil,piy;
+
+   xc  = InXSize >> 1;
+   yc  = InYSize >> 1;
+   roa = MapLR[win].l * InXSize / 360.0;
+   pil = 2.0 * M_PI / InXSize;
+   piy = M_PI / InYSize;
+
+   flam = (fpx - xc - roa) * pil;
+   if (flam < -M_PI) flam += 2.0 * M_PI;
+   if (flam >  M_PI) flam -= 2.0 * M_PI;
+   if (flam < -M_PI_2 || flam > M_PI_2) return 1;
+   fsin = sin(flam);
+   fcos = cos((fpy-yc) * piy);
+   *x2  = xc + InYSize/2 * fcos * fsin;
+   *y2  = yc + InYSize/2 * sin((fpy-yc) * piy);
+   return 0;
+}
+
+void AziLine(int x1, int y1, int x2, int y2)
+{
+   int a1,b1,a2,b2;
+
+   if (AziPoint(x1,y1,&a1,&b1)) return;
+   if (AziPoint(x2,y2,&a2,&b2)) return;
+   XDrawLine(display,pix,gc,a1,b1,a2,b2);
+}
+
+
+/* ======= */
+/* MapLine */
+/* ======= */
+
+void MapLine(INT y, REAL v, REAL Top[], REAL Bot[], INT Dim)
+{
+   INT  f,x;
+   REAL xl,xr,yt,yb;
+   REAL x1,yo,x2,y2,x3,y3,x4,y4;
+
+   for (x=0 ; x < Dim-1 ; x++)
+   {
+      Flag[x] = 0;
+      if (Top[x  ] <  v) Flag[x] |= TOLELO;
+      else               Flag[x] |= TOLEHI;
+      if (Top[x+1] <  v) Flag[x] |= TORILO;
+      else               Flag[x] |= TORIHI;
+      if (Bot[x  ] <  v) Flag[x] |= BOLELO;
+      else               Flag[x] |= BOLEHI;
+      if (Bot[x+1] <  v) Flag[x] |= BORILO;
+      else               Flag[x] |= BORIHI;
+   }
+
+   x = 0;
+
+   while (x < Dim-1)
+   {
+      xl = VGAX *  x   ;
+      xr = VGAX * (x+1);
+      yt = VGAY *  y   ;
+      yb = VGAY * (y+1);
+      f  = Flag[x];
+
+      if (f == 0 || f == (TOLELO | TORILO | BOLELO | BORILO) ||
+		    f == (TOLEHI | TORIHI | BOLEHI | BORIHI))   x++;
+      else if (f == (TOLELO | BORILO | TORIHI | BOLEHI))
+      {
+         x1 = IPX(Top[x  ],v,Top[x+1]);
+         yo = yt;
+         x2 = xr;
+         y2 = IPY(Top[x+1],v,Bot[x+1]);
+         x3 = IPX(Bot[x  ],v,Bot[x+1]);
+         y3 = yb;
+         x4 = xl;
+         y4 = IPY(Top[x  ],v,Bot[x  ]);
+	 AziLine(x1,OffY+yo,x2,OffY+y2);
+	 AziLine(x3,OffY+y3,x4,OffY+y4);
+         ++x;
+      }
+      else if (f == (TORILO | BOLELO | TOLEHI | BORIHI))
+      {
+         x1 = xl;
+         yo = IPY(Top[x  ],v,Bot[x  ]);
+         x2 = IPX(Top[x  ],v,Top[x+1]);
+         y2 = yt;
+         x3 = xr;
+         y3 = IPY(Top[x+1],v,Bot[x+1]);
+         x4 = IPX(Bot[x  ],v,Bot[x+1]);
+         y4 = yb;
+	 AziLine(x1,OffY+yo,x2,OffY+y2);
+	 AziLine(x3,OffY+y3,x4,OffY+y4);
+         ++x;
+      }
+      else
+      {
+	 x1 = x2 = x3 = x4 = -1;
+
+	 if ((Top[x  ] < v && Top[x+1] >= v) || (Top[x  ] >= v && Top[x+1] < v))
+	 {
+	    x1 = IPX(Top[x  ],v,Top[x+1]);
+	    yo = yt;
+	 }
+	 if ((Top[x+1] < v && Bot[x+1] >= v) || (Top[x+1] >= v && Bot[x+1] < v))
+	 {
+	    x2 = xr;
+	    y2 = IPY(Top[x+1],v,Bot[x+1]);
+	 }
+	 if ((Bot[x+1] < v && Bot[x  ] >= v) || (Bot[x+1] >= v && Bot[x  ] < v))
+	 {
+	    x3 = IPX(Bot[x  ],v,Bot[x+1]);
+	    y3 = yb;
+	 }
+	 if ((Bot[x  ] < v && Top[x  ] >= v) || (Bot[x  ] >= v && Top[x  ] < v))
+	 {
+	    x4 = xl;
+	    y4 = IPY(Top[x  ],v,Bot[x  ]);
+	 }
+
+	 if (x1 >= 0 && x2 >= 0 && x3 >= 0 && x4 >= 0)
+	 {
+	    AziLine(x1,OffY+yo,x2,OffY+y2);
+	    AziLine(x3,OffY+y3,x4,OffY+y4);
+	 }
+	 else if (x1 >= 0)
+	 {
+	    if      (x2 >= 0) AziLine(x1,OffY+yo,x2,OffY+y2);
+	    else if (x3 >= 0) AziLine(x1,OffY+yo,x3,OffY+y3);
+	    else              AziLine(x1,OffY+yo,x4,OffY+y4);
+	 }
+	 else if (x2 >= 0)
+	 {
+	    if (x3 >= 0) AziLine(x2,OffY+y2,x3,OffY+y3);
+	    else         AziLine(x2,OffY+y2,x4,OffY+y4);
+	 }
+	 else AziLine(x3,OffY+y3,x4,OffY+y4);
+
+	 x++;
+      }
+   }
+}
+
+
+/* ======== */
+/* MapLines */
+/* ======== */
+
+void MapLines(struct ColorStrip Strip[],int Colored)
+{
+   INT  i;
+   INT  y;
+   REAL *Top;
+   REAL *Bot;
+
+   XSetForeground(display,gc,BlackPix);
+   i = 0;
+   while (Strip[i].Name)
+   {
+      Top = Field;
+      Bot = Field + DimX;
+      if (Colored) XSetForeground(display,gc,Strip[i].pixel);
+      for (y = 0 ; y < DimY-1 ; y++)
+      {
+	 MapLine(y,Strip[i].Lo,Top,Bot,DimX);
+	 Top += DimX;
+	 Bot += DimX;
+      }
+      ++i;
+   }
+}
+
+int polco = 0;
+
+void poltra(float lam, float phi, float *x, float *y)
+{
+   REAL xnp,ynp,xsp,ysp,lfa;
+
+   lfa = (2.0 * M_PI) / (InXSize-1) ;
+   xnp = (InXSize-1) * 0.25;
+   ynp = (InYSize-1) * 0.50;
+   xsp = (InXSize-1) * 0.75;
+   ysp = ynp;
+
+   /* Northern hemisphere */
+
+   if (phi < ynp)
+   {
+      *x = xnp + sin(lam * lfa) * phi;
+      *y = ynp + cos(lam * lfa) * phi;
+   }
+
+   /* Souhern hemisphere */
+
+   else
+   {
+      *x = xsp - sin(lam * lfa) * (phi-ysp);
+      *y = ysp + cos(lam * lfa) * (phi-ysp);
+   }
+}
+
+
+/* ========== */
+/* TracerPlot */
+/* ========== */
+
+void TracerPlot(int w)
+{
+   int j,ipx,ipy,lpy,lpx,jx,jy,ic,ix,iy,ipr;
+   int xnp,ynp,xsp,ysp,xc,yc;
+   float *u;
+   float *v;
+   float fpx,fpy,du,dv,ppx,ppy,rx,ry,spfac;
+   float lfa,lam,phi,hpy,fcos,fsin;
+   float pil,piy;
+   float roa;
+   float flam;
+   float dpx,dpy;
+   float rary,alpy;
+
+   if (Uindex < 0 || Vindex < 0) return; // Data missing
+
+   Delpar = (8 * 60) / DeltaTime; // Injection interval
+   if (LevelChanged[w]) ClearTracer();
+   LevelChanged[w] = 0;
+   if (!SpeedScale) SpeedScale = FloatAlloc(DimY,"SpeedScale");
+   u = Array[Uindex].Data + Indez[w] * DimXY;
+   v = Array[Vindex].Data + Indez[w] * DimXY;
+
+   TracerColor = Yellow.pixel;
+   if (nstep % (8*Delpar) == 0) ColInd++;
+   if (ColInd >= AUTOCOLORS) ColInd = 0;
+   TracerColor = Autostrip[ColInd].pixel;
+
+   dpx  = (float)(InXSize-1) / (float)(DimX-1);
+   dpy  = (float)(InYSize-1) / (float)(DimY-1);
+   lpx  = InXSize;
+   lpy  = InYSize;
+   hpy  = 0.5 * dpy;
+   xc   = lpx / 2;
+   yc   = lpy / 2;
+   pil  = 2.0 * M_PI / lpx;
+   piy  = M_PI / lpy;
+   roa  = MapLR[w].l * lpx / 360.0;
+   rary = 1.0 / ary;
+   alpy = rary * lpy;
+   ipr  = rary * InYSize / 80.0; // Size of tracer dots
+
+   // Compute scale factors
+
+   if (SizeChanged || nstep < 10)
+   {
+      for (j=0 ; j < DimY; ++j)
+      {
+         SpeedScale[j] = InXSize * DeltaTime * 60.0 / 40000000.0 
+                       / cos((j-0.5*(DimY-1)) * (M_PI/DimY));
+      }
+      SpeedScale[DimY-1] = SpeedScale[0] = SpeedScale[1];
+   }
+
+   // Insert new particles
+
+   if (nstep % Delpar == 0)
+   {
+      fpx = dpx * (DimX-1) / 2.0;
+      for (ipy = 0 ; ipy < lpy ; ipy += dpy)
+      {
+         ParInd = (ParInd+1) & (MAXPAR-1);
+         pax[ParInd] = fpx;
+         pay[ParInd] = ipy + hpy;
+         pal[ParInd] = TracerColor;
+      }
+   }
+
+  // Move particles
+
+  for (j=0 ; j < MAXPAR ; ++j)
+  if (pax[j] >= 0.0 && pay[j] >= 0.0)
+  {
+     jx = rx = pax[j] / dpx;
+     jy = ry = pay[j] / dpy;
+     ic = jx + DimX * jy;
+     ix = ic + 1;
+     if (jx >= DimX-1) ix -= DimX;
+     iy = ic + DimX;
+     if (iy >= DimX * DimY) iy -= DimX;
+     rx -= jx;
+     ry -= jy;
+
+     du = u[ic]+(u[ix]-u[ic])*rx+(u[iy]-u[ic])*ry;
+     dv = v[ic]+(v[ix]-v[ic])*rx+(v[iy]-v[ic])*ry;
+     spfac = SpeedScale[jy] + (SpeedScale[jy+1]-SpeedScale[jy]) * ry;
+     du *= spfac;
+     dv *= spfac;
+     fpx = pax[j] + du;
+     fpy = pay[j] + dv;
+     if (fpx <  0.0) fpx += lpx;
+     if (fpx >= lpx) fpx -= lpx;
+     if (fpy < 0.0 || fpy > lpy-1)
+     {
+        pay[j] = -1.0;
+        continue;
+     }
+     pax[j] = fpx;
+     pay[j] = fpy;
+     ipx    =  -1;
+     if (MapPro[w] == POLAR)
+     {
+       lfa = (2.0 * M_PI) / lpx;
+       xnp = (InXSize-1) * 0.25;
+       ynp = (InYSize-1) * 0.50;
+       xsp = (InXSize-1) * 0.75;
+       ysp = ynp;
+       lam = fpx;
+       phi = fpy * rary;
+       if (fpy < 0.5 * lpy) /* Northern hemisphere */
+       {
+          fpx = xnp - sin(lam * lfa) * (phi + hpy);
+          fpy = ynp - cos(lam * lfa) * (phi + hpy);
+       }
+       else                 /* Souhern hemisphere */
+       {
+          fpx = xsp + sin(lam * lfa) * (alpy - phi + hpy);
+          fpy = ysp - cos(lam * lfa) * (alpy - phi + hpy);
+       }
+       ipx = rintf(fpx);
+       ipy = rintf(fpy);
+     }
+     else if (MapPro[w] == AZIMUTHAL)
+     {
+        flam = (fpx - xc - roa) * pil;
+        if (flam < -M_PI) flam += 2.0 * M_PI;
+        if (flam >  M_PI) flam -= 2.0 * M_PI;
+        if (flam < -M_PI_2 || flam > M_PI_2) continue;
+        fsin = sin(flam);
+        fcos = cos((fpy-yc) * piy);
+        fpx  = xc + lpy/2 * fcos * fsin;
+        fpy  = yc + lpy/2 * sin((fpy-yc) * piy);
+        ipx  = rintf(fpx);
+        ipy  = rintf(fpy);
+     }
+     else
+     {
+        ipx = rintf(fpx);
+        ipy = rintf(fpy);
+     }
+     if (ipx >= 0)
+     {
+        XSetForeground(display,gc,pal[j]);
+        if (ipr < 2) XDrawPoint(display,pix,gc,ipx,ipy);
+        else if (ipr == 2) XFillRectangle(display,pix,gc,ipx,ipy,2,2);
+        else XFillArc(display,pix,gc,ipx,ipy,ipr,ipr,0,360*64);
+     }
+  }
+}
+
+
+/* ============= */
+/* AmplitudePlot */
+/* ============= */
+
+void AmplitudePlot(void)
+{
+   int i,j,m,n;
+   int x,y;
+   int r,dx,dy;
+   int mmax;
+   int imax;
+   REAL Amax,Fac;
+
+   if (!Ampli) Ampli = FloatAlloc(DimX,"Ampli");
+   if (!Acol ) Acol  = SizeAlloc(DimX,sizeof(XColor),"Acol");
+
+   Amax = 0.0;
+   imax = 0;
+   for (i=0 ; i < DimX ; ++i)
+   {
+      Ampli[i] = log (1.0 + sqrt(Field[2*i]*Field[2*i]+Field[2*i+1]*Field[2*i+1]));
+      Acol[i].pixel = WhitePix;
+      if (Ampli[i] > Amax && i > DimY)
+      {
+         Amax = Ampli[i];
+         imax = i;
+      }
+   }
+
+   Fac = 0.0;
+   if (Amax > 1.e-20) Fac = 1.0 / Amax;
+   for (i=0 ; i < DimX ; ++i)
+   {
+      j = AMPLI_COLS * Ampli[i] * Fac;
+      if (j >= AMPLI_COLS) j = AMPLI_COLS-1;
+      Acol[i].pixel = AmpliStrip[j].pixel;
+   }
+
+   dx = WinXSize / 23;
+   r  = (dx+dx) / 3;
+   mmax = (InYSize / dx) - 1;
+   XSetForeground(display,gc,BlackPix);
+   for (m=0,i=0 ; m < mmax ; ++m)
+   {
+      y = FixFontHeight + 4 + m * dx;
+      for (n=m ; n < DimY ; ++n,++i)
+      if (n < 22)
+      {
+         x = dx/2 + n * dx;
+         XSetForeground(display,gc,Acol[i].pixel);
+         XFillArc(display,pix,gc,x,y,r,r,0,360*64);
+      }
+   }
+}
+
+
+void RedrawIsoWindow(int w)
+{
+   if (WinPixMap[w].Pix)
+   XCopyArea(display,WinPixMap[w].Pix,Win[w],gc,0,0,WinPixMap[w].DimX,WinPixMap[w].DimY,0,0);
+}
+
+
+void CloseWindow(int i)
+{
+   INTXS X,Y,xp,yp;
+   unsigned int border,depth;
+   Window Rootwin,Child;
+
+   if (Win[i])
+   {
+       XGetGeometry(display,Win[i],&Rootwin,&xp,&yp,&WinAtt[i].w,&WinAtt[i].h,&border,&depth);
+       XTranslateCoordinates(display,Win[i],Rootwin,0,0,&X,&Y,&Child);
+       WinAtt[i].x =  X - WinLM;
+       WinAtt[i].y =  Y - WinTM;
+       XDestroyWindow(display,Win[i]);
+       Win[i] = 0;
+       ShowWindowStatus();
+   }
+}
+
+void ReopenWindow(int i)
+{
+   if (Win[i] == 0)
+   {
+      if (WinAtt[i].x < ScreenOffset) WinAtt[i].x = ScreenOffset + OutXSize * (i % WinCols);
+      if (WinAtt[i].y < ScreenOffset) WinAtt[i].y = ScreenOffset + OutYSize * (i / WinCols);
+      Win[i] = XCreateSimpleWindow(display,RootWindow(display,screen_num), 
+               WinAtt[i].x,WinAtt[i].y,WinAtt[i].w,WinAtt[i].h,
+               BorderWidth,BlackPix,WhitePix);
+      XSetWMProtocols(display,Win[i],&Delwin,1);
+      XSetWMProperties(display,Win[i],WindowName+i,NULL,
+		NULL,0,&WinSizeHints,&wm_hints,&class_hints);
+      XSelectInput(display,Win[i],ButtonPressMask | KeyPressMask | ExposureMask);
+      XMapWindow(display,Win[i]);
+      ShowWindowStatus();
+   }
+}
+
+char *HelpText[] =
+{
+   "Key assignment for azimuthal projection     ",
+   "--------------------------------------------",
+   "<- cursor left  : increase westward rotation",
+   "-> cursor right : increase eastward rotation",
+   "============================================",
+   "Key assignment for 3D variables             ",
+   "--------------------------------------------",
+   "^  cursor up    : display next upper level  ",
+   "v  cursor down  : display next lower level  ",
+   "============================================",
+   "Key assignment for Lon/Lev or Hovmoeller    ",
+   "--------------------------------------------",
+   "^  cursor up    : switch latitude northwards",
+   "v  cursor down  : switch latitude southwards",
+   "============================================",
+   "Mouse button assignment                     ",
+   "--------------------------------------------",
+   "Left   button   : decrease level or latitude",
+   "Right  button   : increase level or latitude",
+   "Middle button   : cycle through projections "
+};
+
+int HelpLines = sizeof(HelpText) / sizeof(char *);
+
+void DrawHelpWindow(void)
+{
+   int x,y,j,l;
+
+   XSetForeground(display,gc,Yellow.pixel);
+   XSetBackground(display,gc,DarkBlue.pixel);
+   XSetFont(display,gc,BigFont->fid);
+
+   x = BigFontWidth / 2;
+   for (j=0 ; j < HelpLines ; ++j)
+   {
+      y = BigFontHeight / 2 + BigFont->ascent + j * BigFontHeight;
+      l = strlen(HelpText[j]);
+      XDrawImageString(display,HelpWindow,gc,x,y,HelpText[j],l);
+   }
+}
+
+void DisplayHelpWindow(void)
+{
+   int x,y,w,h;
+   char *HelpTitle = "Help";
+
+   w = BigFontWidth  * (strlen(HelpText[0])+1);
+   h = BigFontHeight * (HelpLines + 1);
+   x = (ScreenW - w) / 2;
+   y = (ScreenH - h) / 2;
+   HelpWindow = XCreateSimpleWindow(display,RootWindow(display,screen_num), 
+                x,y,w,h,BorderWidth,Yellow.pixel,DarkBlue.pixel);
+   XStringListToTextProperty(&HelpTitle,1,&HelpName);
+   XSetWMProtocols(display,HelpWindow,&Delwin,1);
+   XSetWMProperties(display,HelpWindow,&HelpName,NULL,NULL,0,NULL,NULL,NULL);
+   XSelectInput(display,HelpWindow,ButtonPressMask | ExposureMask);
+   XMapWindow(display,HelpWindow);
+   XMoveWindow(display,HelpWindow,x,y);
+   DrawHelpWindow();
+}
+
+int HitGridButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Grid_XL  ) &&
+   (xe->xbutton.x <= Grid_XH  ) &&
+   (xe->xbutton.y >= Grid_YL  ) &&
+   (xe->xbutton.y <= Grid_YH  ));
+}
+
+int HitPauseButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Pause_XL-2  ) &&
+   (xe->xbutton.x <= Pause_XH+2  ) &&
+   (xe->xbutton.y >= Pause_YL-2  ) &&
+   (xe->xbutton.y <= Pause_YH+2  ));
+}
+
+int HitStartButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Start_XL-2  ) &&
+   (xe->xbutton.x <= Start_XH+2  ) &&
+   (xe->xbutton.y >= Start_YL-2  ) &&
+   (xe->xbutton.y <= Start_YH+2  ));
+}
+
+int HitStopButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Stop_XL-2   ) &&
+   (xe->xbutton.x <= Stop_XH+2   ) &&
+   (xe->xbutton.y >= Stop_YL-2   ) &&
+   (xe->xbutton.y <= Stop_YH+2   ));
+}
+
+int HitHelpButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Help_XL-2   ) &&
+   (xe->xbutton.x <= Help_XH+2   ) &&
+   (xe->xbutton.y >= Help_YL-2   ) &&
+   (xe->xbutton.y <= Help_YH+2   ));
+}
+
+int HitPlusButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Plus_XL  ) &&
+   (xe->xbutton.x <= Plus_XH  ) &&
+   (xe->xbutton.y >= Plus_YL  ) &&
+   (xe->xbutton.y <= Plus_YH  ));
+}
+
+int HitFFWDButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= FFWD_XL  ) &&
+   (xe->xbutton.x <= FFWD_XH  ) &&
+   (xe->xbutton.y >= FFWD_YL  ) &&
+   (xe->xbutton.y <= FFWD_YH  ));
+}
+
+int HitMinusButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Minus_XL  ) &&
+   (xe->xbutton.x <= Minus_XH  ) &&
+   (xe->xbutton.y >= Minus_YL  ) &&
+   (xe->xbutton.y <= Minus_YH  ));
+}
+
+int HitFBWDButton(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= FBWD_XL  ) &&
+   (xe->xbutton.x <= FBWD_XH  ) &&
+   (xe->xbutton.y >= FBWD_YL  ) &&
+   (xe->xbutton.y <= FBWD_YH  ));
+}
+
+int HitUpperPanel(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Parc_XL  ) &&
+   (xe->xbutton.x <= Parc_XH  ) &&
+   (xe->xbutton.y >= Parc_YL-Parc_YD  ) &&
+   (xe->xbutton.y <= Parc_YL  ));
+}
+
+int HitLowerPanel(XEvent* xe)
+{
+   return (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Parc_XL  ) &&
+   (xe->xbutton.x <= Parc_XH  ) &&
+   (xe->xbutton.y >= Parc_YH  ) &&
+   (xe->xbutton.y <= Parc_YH+Parc_YD));
+}
+
+int HitWindowSelect(XEvent* xe)
+{
+   if (
+   (xe->xbutton.button == Button1) &&
+   (xe->xbutton.x >= Wbox_XL) &&
+   (xe->xbutton.x <= Wbox_XH) &&
+   (xe->xbutton.y >= Wbox_YL) &&
+   (xe->xbutton.y <= Wbox_YH))
+      return (xe->xbutton.y / FixFontHeight); /* Window number */
+   else return -1;
+}
+
+void OnMouseClick(void)
+{
+   int w;
+
+   if (HitStopButton(&CowEvent))
+   {
+      Shutdown = 1;
+   }
+   else if (HitStartButton(&CowEvent))
+   {
+      Paused = 0;
+      XSetWMName(display,Cow,&WinconName1);
+   }
+   else if (HitGridButton(&CowEvent))
+   {
+      Grid = !Grid;
+      ShowGridStatus();
+      for (w=0 ; w < NUMWIN ; ++w) RedrawFlag[w] = 1;
+   }
+   else if (HitPauseButton(&CowEvent))
+   {
+      if (Paused)
+      {
+         Paused = 0;
+         XSetWMName(display,Cow,&WinconName1);
+      }
+      else
+      {
+         Paused = 1;
+         XSetWMName(display,Cow,&WinconPause);
+      }
+   }
+   else if (HitHelpButton(&CowEvent))
+   {
+      if (!HelpWindow) DisplayHelpWindow();
+   }
+   else if ((w = HitWindowSelect(&CowEvent)) >= 0)
+   {
+      if (Win[w]) CloseWindow(w);
+      else        ReopenWindow(w);
+   }
+   else if (HitPlusButton(&CowEvent))
+   {
+      Parc[cpi].Val += Parc[cpi].Inc;
+      if (Parc[cpi].Val > Parc[cpi].Max) Parc[cpi].Val = Parc[cpi].Max;
+   }
+   else if (HitFFWDButton(&CowEvent))
+   {
+      Parc[cpi].Val += 10.0 * Parc[cpi].Inc;
+      if (Parc[cpi].Val > Parc[cpi].Max) Parc[cpi].Val = Parc[cpi].Max;
+   }
+   else if (HitMinusButton(&CowEvent))
+   {
+       Parc[cpi].Val -= Parc[cpi].Inc;
+      if (Parc[cpi].Val < Parc[cpi].Min) Parc[cpi].Val = Parc[cpi].Min;
+   }
+   else if (HitFBWDButton(&CowEvent))
+   {
+       Parc[cpi].Val -= 10.0 * Parc[cpi].Inc;
+      if (Parc[cpi].Val < Parc[cpi].Min) Parc[cpi].Val = Parc[cpi].Min;
+   }
+   else if (HitUpperPanel(&CowEvent) && cpi > 0) --cpi;
+   else if (HitLowerPanel(&CowEvent) && cpi < Parcs-1) ++cpi;
+}
+
+
+void SwitchIndez(int w, int d)
+{
+   int jlat;
+   REAL delphi;
+   char *lpt;
+   char levstr[20];
+
+   if (Indez[w] < 0 || Indez[w] >= MaxZ[w])
+   {
+      if (Debug) printf("### Indez[%d] = %d\n",w,Indez[w]);
+      if (Debug) printf("###  MaxZ[%d] = %d\n",w, MaxZ[w]);
+      Indez[w] = 0;
+   }
+   if (Indez[w]+d <  0      ) return;
+   if (Indez[w]+d >= MaxZ[w]) return;
+   Indez[w] += d;
+   lpt = strstr(WindowTitle[w],"Level");
+   if (lpt)
+   {
+      sprintf(levstr," %d",Indez[w]+1);
+      strcpy(lpt+5,levstr);
+      XStringListToTextProperty(&WindowTitle[w],1,WindowName+w);
+      XSetWMProperties(display,Win[w],WindowName+w,NULL,
+		NULL,0,&WinSizeHints,&wm_hints,&class_hints);
+      LevelChanged[w] = 1;
+      return;
+   }
+   lpt = strstr(WindowTitle[w],"Latitude");
+   if (lpt)
+   {
+      delphi = 180.0 / MaxZ[w];
+      jlat = 90.0 -Indez[w] * delphi - delphi * 0.5;
+      if (jlat > 0) sprintf(levstr," %dN", jlat);
+      else          sprintf(levstr," %dS",-jlat);
+      strcpy(lpt+8,levstr);
+      XStringListToTextProperty(&WindowTitle[w],1,WindowName+w);
+      XSetWMProperties(display,Win[w],WindowName+w,NULL,
+		NULL,0,&WinSizeHints,&wm_hints,&class_hints);
+      return;
+   }
+}
+
+
+void HandleEvents(void)
+{
+   int w,Key,KeyIndex;
+   XEvent WinEvent;
+
+   if (nstep == 1)
+   {
+      RedrawControlWindow();
+      Paused = 1; /* Start in pause mode */
+   }
+
+
+   do
+   {
+      /* Check for Termination */
+
+      if (XCheckTypedWindowEvent(display,Cow,ClientMessage,&WinEvent))
+      {
+         /* printf("delwin %d\n",WinEvent.xclient.data.l[0]); */
+         Shutdown = 1;
+         return;
+      }
+
+      /* Check for user request to close windows */
+
+      for (w=0 ; w < NumWin ; ++w)
+      if (Win[w])
+      {
+         if (XCheckTypedWindowEvent(display,Win[w],ClientMessage,&WinEvent))
+         CloseWindow(w);
+      }
+
+      /* Check for user request to close help window */
+
+      if (HelpWindow && XCheckTypedWindowEvent(display,HelpWindow,ClientMessage,&WinEvent))
+      {
+         XDestroyWindow(display,HelpWindow);
+         HelpWindow = 0;
+      }
+
+      /* Check for mouse click */
+
+      if (XCheckTypedWindowEvent(display,Cow,ButtonPress,&CowEvent))
+      {
+         OnMouseClick();
+         RedrawControlWindow();
+      }
+
+      /* Check for mouseclicks and expose events */
+
+      for (w=0 ; w < NumWin ; ++w)
+      if (Win[w])
+      {
+         if (XCheckTypedWindowEvent(display,Win[w],ButtonPress,&CowEvent))
+         {
+           if (CowEvent.xbutton.button == Button1) SwitchIndez(w,-1);
+           if (CowEvent.xbutton.button == Button3) SwitchIndez(w, 1);
+           if (CowEvent.xbutton.button == Button2)
+           {
+              if (++MapPro[w] >= MAXMAPS) MapPro[w] = 0;
+              if (MapPro[w] == AZIMUTHAL &&
+                 (WinAtt[w].Plot != MAPHOR && WinAtt[w].Plot != MAPTRA))
+                 MapPro[w] = 0;
+           }
+           RedrawFlag[w] = 1;
+         }
+         if (XCheckTypedWindowEvent(display,Win[w],KeyPress,&CowEvent))
+         {
+            KeyIndex = (CowEvent.xkey.keycode - FirstKey) * SymsPerKey;
+            Key = KeyMap[KeyIndex];
+            if (Debug) printf("Windows %d got keyindex %d with symbol %x\n",w,KeyIndex,Key);
+            if (Key == ROTATE_LEFT  && MapLR[w].f <  5) MapLR[w].f++;
+            if (Key == ROTATE_RIGHT && MapLR[w].f > -5) MapLR[w].f--;
+            MapLR[w].r = MapLR[w].f * RotInc;
+            if (Key == XK_Up  ) SwitchIndez(w,-1);
+            if (Key == XK_Down) SwitchIndez(w, 1);
+         }
+         if (Paused)
+         if (XCheckTypedWindowEvent(display,Win[w],Expose,&CowEvent))
+                     RedrawIsoWindow(w);
+      }
+
+      if (XCheckTypedWindowEvent(display,Cow,Expose,&CowEvent))
+         RedrawControlWindow();
+
+      if (HelpWindow && XCheckTypedWindowEvent(display,HelpWindow,Expose,&CowEvent))
+         DrawHelpWindow();
+
+   } while (Paused && !Shutdown);
+}
+
+void guiclose_(void)
+{
+   int w;
+
+   if (MRpid >= 0) return; // Don't wait if multiple instances
+   XSetWMName(display,Cow,&WinconName3);
+
+   do
+   {
+      for (w=0 ; w < NumWin ; ++w)
+      if (Win[w])
+      {
+         if (XCheckTypedWindowEvent(display,Win[w],Expose,&CowEvent))
+                     RedrawIsoWindow(w);
+      }
+
+      if (XCheckTypedWindowEvent(display,Cow,Expose,&CowEvent))
+         RedrawControlWindow();
+   }
+   while (!(XCheckTypedWindowEvent(display,Cow,ButtonPress,&CowEvent) &&
+            HitStopButton(&CowEvent)));
+     
+// XCloseDisplay(display); // segmentation fault on sun compiler!
+}
+
+void SaveConfig(void)
+{
+   int i;
+   FILE *scp;
+   INTXS X,Y,xp,yp;
+   unsigned int w,W,H,border,depth;
+   Window Rootwin,Child;
+   XWindowAttributes RootAtt;
+
+   scp = fopen(GUI_config,"w");
+   if (scp == NULL) return;
+
+   /* Save window properties */
+
+   fprintf(scp,"Hamburg GUI Config File Version 16\n");
+   fprintf(scp,"Screen: %dx%d\n\n",ScreenW,ScreenH);
+   fprintf(scp,"WinRows = %d\n",WinRows);
+   fprintf(scp,"WinCols = %d\n",WinCols);
+   for (w=0 ; w < NumWin ; ++w)
+   {
+      fprintf(scp,"\n[Window %02d]\n",w);
+      fprintf(scp,"Array:%s\n",WinAtt[w].array_name);
+      fprintf(scp,"Plot:%s\n",IsoNames[WinAtt[w].Plot]);
+      if (WinAtt[w].Plot == ISOHOR || WinAtt[w].Plot == MAPHOR ||
+          WinAtt[w].Plot == ISOTRA || WinAtt[w].Plot == MAPTRA)
+      {
+         fprintf(scp,"Projection:%s\n",ProNames[MapPro[w]]);
+         fprintf(scp,"Rotation factor:%d\n",MapLR[w].f);
+      }
+      fprintf(scp,"Palette:%s\n",PalNames[WinAtt[w].Palette]);
+      fprintf(scp,"Title:%s\n",WindowTitle[w]+wto);
+      if (Win[w])
+      {
+         XGetGeometry(display,Win[w],&Rootwin,&xp,&yp,&W,&H,&border,&depth);
+         XTranslateCoordinates(display,Win[w],Rootwin,0,0,&X,&Y,&Child);
+         fprintf(scp,"Geometry: %4d %4d %4d %4d\n",W,H,X-WinLM,Y-WinTM);
+         if (Debug)
+         {
+            printf("Geometry Window %d   [%8x]: %4d / %4d   %4d x %4d x %2d | %d\n",
+                  w,(int)Win[w],xp,yp,W,H,depth,border);
+            printf("Translated UL corner: %4d / %4d\n",X,Y);
+         }
+      }
+      else
+         fprintf(scp,"Inactive: %4d %4d %4d %4d\n",
+                 WinAtt[w].w,WinAtt[w].h,WinAtt[w].x,WinAtt[w].y);
+   }
+   XGetGeometry(display,Cow,&Rootwin,&xp,&yp,&W,&H,&border,&depth);
+   XTranslateCoordinates(display,Cow,Rootwin,0,0,&X,&Y,&Child);
+   fprintf(scp,"\n[Control Window]\n");
+   fprintf(scp,"Geometry: %4d %4d %4d %4d\n",W,H,X-WinLM,Y-WinTM);
+
+   /* Scalar attributes for timeseries and tables */
+
+   fprintf(scp,"\n# Scalar attributes for timeseries and table window\n");
+
+   for (i=0 ; i < Parcs ; ++i)
+   {
+      fprintf(scp,"\n[Scalar %02d]\n",i);
+      fprintf(scp,"Name:%s\n",TSName[i]);
+      fprintf(scp,"Sub:%s\n",TSubsc[i]);
+      fprintf(scp,"Unit:%s\n",TSUnit[i]);
+      fprintf(scp,"Scale:%s\n",TScale[i]);
+   }
+
+   /* Scalar attributes for timeseries and tables */
+
+    fprintf(scp,"\n# Parameter attributes for change menu\n");
+
+   for (i=0 ; i < NUMSCALARS ; ++i)
+   {
+      if (strlen(Parc[i].Name) == 0) break;
+      fprintf(scp,"\n[Parameter %02d]\n",i);
+      fprintf(scp,"ParName:%s\n",Parc[i].Name);
+      fprintf(scp,"ParInc:%10.4f\n",Parc[i].Inc);
+      fprintf(scp,"ParMin:%10.4f\n",Parc[i].Min);
+      fprintf(scp,"ParMax:%10.4f\n",Parc[i].Max);
+   }
+
+   fclose(scp);
+}
+
+/* Transform a lambda/hi grid to polar stereographic projection */
+/* Input array a and output array b have identical dimensions   */
+
+void lp2ps(REAL *a, REAL *b)
+{
+   int i,j,k,l,k1,l1;
+   REAL xnp,ynp,xsp,ysp,dx,dy,x,y,lfa,ua,ub;
+
+   lfa = (DimX-1) / (2.0 * M_PI);
+   xnp = (DimX-1) * 0.25; // Northpole at (xnp,ynp)
+   ynp = (DimY-1) * 0.50;
+   xsp = (DimX-1) * 0.75; // Southpole at (xsp,ysp)
+   ysp = ynp;
+
+   // Interpolate b[i][j] from a[k][l]
+
+   /* Northern hemisphere */
+
+   for (j = 0 ; j <  DimY   ; ++j)
+   for (i = 0 ; i <= DimX/2 ; ++i)
+   {
+      dx = arx * (xnp - i);
+      dy = ary * (ynp - j);
+      x = atan2(dx,dy) * lfa;      // angle 
+      y = sqrt(dx * dx + dy * dy); // distance from NP
+      if (x < 0.0) x += (DimX-1);
+      k = x;                       // integer part
+      l = y;
+      k1 = k + 1;
+      if (k1 >= DimX) k1 = 0;
+      if (l <= DimY/2+1)           // Northern hemisphere
+      {
+         ua = (k+1-x) *  a[k+l*DimX] + (x-k) * a[k1+l*DimX];
+         ub = (k+1-x) * a[k+(l+1)*DimX] + (x-k) * a[k+1+(l+1)*DimX];
+         b[i+j*DimX] = (l+1-y) * ua + (y-l) * ub;
+      }
+      else b[i+j*DimX] = - 99999.0;
+   }
+
+   /* Souhern hemisphere */
+
+   for (j = 0        ; j < DimY ; ++j)
+   for (i = DimX/2+1 ; i < DimX ; ++i)
+   {
+      dx = arx * (i - xsp);
+      dy = ary * (ysp - j);
+      x = atan2(dx,dy) * lfa;
+      y = (DimY-1) - sqrt(dx * dx + dy * dy);
+      if (x < 0.0) x += (DimX-1);
+      k = x;
+      l = y;
+      k1 = k + 1;
+      if (k1 >= DimX) k1 = 0;
+      if (l >= DimY/2-3)
+      {
+         ua = (k+1-x) *  a[k+l*DimX] + (x-k) * a[k1+l*DimX];
+         ub = (k+1-x) * a[k+(l+1)*DimX] + (x-k) * a[k+1+(l+1)*DimX];
+         b[i+j*DimX] = (l+1-y) * ua + (y-l) * ub;
+      }
+      else b[i+j*DimX] = - 99999.0;
+   }
+}
+
+
+/* ======================================================= */
+/* lp2az - transform lon/lat array to azimuthal projection */
+/* ======================================================= */
+
+void lp2az(REAL *a, REAL *b, float laz)
+{
+   int x,y,dxc,k,k1,l;
+   REAL dx,dy,lam,rho,rad,phi,ua,ub,l00,p00,xpi,ypi;
+
+   rad = DimY >> 1;
+   dxc = DimX >> 1;
+   xpi = DimX / M_PI * 0.5;
+   ypi = DimY / M_PI;
+   l00 =  (int)((laz * DimX) / 360 + dxc) % DimX;
+   p00 = DimY / 2;
+
+   for (y = 0 ; y < DimY ; ++y)
+   {
+      dy  = y - rad;
+      phi = y;
+      for (x = 0 ; x < DimX ; ++x)
+      {
+         dx = x - dxc;
+         rho = sqrt(dx * dx + dy * dy);
+         if (rho < rad)
+         {
+            lam = l00 + xpi * atan2(dx / rad, cos(asin(rho / rad)));
+            phi = p00 + ypi *  asin(dy / rad);
+            k = lam;
+            k1 = k + 1;
+            if (k1 >= DimX) k1 = 0;
+            l = phi;
+            ua = (k+1-lam) * a[k+ l   *DimX] + (lam-k) * a[k1 + l   *DimX];
+            ub = (k+1-lam) * a[k+(l+1)*DimX] + (lam-k) * a[k+1+(l+1)*DimX];
+            b[x+y*DimX] = (l+1-y) * ua + (y-l) * ub;
+         }
+         else b[x+y*DimX] = - 99999.0;
+      }
+   }
+}
+
+void ShowGridCS(void)
+{
+   int jlev,jlat,x,y,len;
+   float dx,dy;
+   char Text[80];
+
+   /* Grid for zonal mean cross sections */
+
+   XSetForeground(display,gc,WhitePix);
+   XSetBackground(display,gc,BlackPix);
+   XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   dy = (InYSize - OffY) / (DimY - 1.0);
+   for (jlev = 1 ; jlev < DimY-1 ; ++jlev)
+   {
+      y = OffY + jlev * dy;
+      XDrawLine(display,pix,gc,OffX,y,InXSize-1,y);
+   }
+   dx = (InXSize - OffX) / 6.0; /* Every 30 degrees */
+   for (jlat = 1 ; jlat < 6 ; ++jlat)
+   {
+      x = OffX + jlat * dx;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize-1);
+   }
+   if (GridLabel)
+   {
+      XDrawImageString(display,pix,gc,InXSize/2-FixFontWidth,InYSize-FixFont->descent,"EQ",2);
+      XDrawImageString(display,pix,gc,OffX,InYSize-FixFont->descent,"N",1);
+      XDrawImageString(display,pix,gc,InXSize-FixFontWidth,InYSize-FixFont->descent,"S",1);
+   }
+   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+}
+
+void ShowGridCol(void)
+{
+   int jlev,jtim,x,y,len;
+   float dx,dy;
+   char Text[80];
+
+   /* Grid for column time series */
+
+   XSetForeground(display,gc,WhitePix);
+   XSetBackground(display,gc,BlackPix);
+   XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   dy = (InYSize - OffY) / (DimY - 1.0);
+   for (jlev = 1 ; jlev < DimY-1 ; ++jlev)
+   {
+      y = OffY + jlev * dy;
+      XDrawLine(display,pix,gc,OffX,y,InXSize-1,y);
+   }
+   dx = (InXSize - OffX) / 4.0; /* 4 slices */
+   for (jtim = 1 ; jtim < 4 ; ++jtim)
+   {
+      x = OffX + jtim * dx;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize-1);
+   }
+   if (GridLabel)
+   {
+      XDrawImageString(display,pix,gc,InXSize/2-3*FixFontWidth/2,InYSize-FixFont->descent,"t-2",3);
+      XDrawImageString(display,pix,gc,InXSize/4-3*FixFontWidth/2,InYSize-FixFont->descent,"t-3",3);
+      XDrawImageString(display,pix,gc,3*InXSize/4-3*FixFontWidth/2,InYSize-FixFont->descent,"t-1",3);
+   }
+   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+}
+
+void ShowGridLonsi(void)
+{
+   int jlev,jlat,x,y,len;
+   float dx,dy;
+   char Text[80];
+
+   /* Grid for Longitude Sigma section */
+
+   XSetForeground(display,gc,WhitePix);
+   XSetBackground(display,gc,BlackPix);
+   XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   dy = (InYSize - OffY) / (DimY - 1.0);
+   for (jlev = 1 ; jlev < DimY-1 ; ++jlev)
+   {
+      y = OffY + jlev * dy;
+      XDrawLine(display,pix,gc,OffX,y,InXSize-1,y);
+   }
+   dx = (InXSize - OffX) / 6.0; /* Every 60 degrees */
+   for (jlat = 1 ; jlat < 6 ; ++jlat)
+   {
+      x = OffX + jlat * dx;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize-1);
+   }
+   if (GridLabel)
+   {
+      XDrawImageString(display,pix,gc,InXSize/2-3*FixFontWidth/2,InYSize-FixFont->descent,"180",3);
+      XDrawImageString(display,pix,gc,OffX,InYSize-FixFont->descent,"0",1);
+      XDrawImageString(display,pix,gc,InXSize-3*FixFontWidth,InYSize-FixFont->descent,"360",3);
+   }
+   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+}
+
+void ShowGridCyl(void)
+{
+   int jlon,jlat,x,y;
+   float dx,dy;
+
+   /* Grid for cylinder projection */
+
+   XSetForeground(display,gc,WhitePix);
+   XSetBackground(display,gc,BlackPix);
+   XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   dy = (InYSize - OffY) / 6.0;
+   for (jlat = 1 ; jlat < 6 ; ++jlat)
+   {
+      y = OffY + jlat * dy;
+      XDrawLine(display,pix,gc,OffX,y,InXSize-1,y);
+   }
+   dx = (InXSize - OffX) / 6.0; /* Every 30 degrees */
+   for (jlon = 1 ; jlon < 6 ; ++jlon)
+   {
+      x = OffX + jlon * dx;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize-1);
+   }
+   if (GridLabel)
+   {
+      XDrawImageString(display,pix,gc,OffX,OffY+(InYSize-OffY)/2+FixFontHeight/2-FixFont->descent,"EQ",2);
+      XDrawImageString(display,pix,gc,OffX,OffY+FixFontHeight-FixFont->descent,"N",1);
+      XDrawImageString(display,pix,gc,OffX,InYSize-FixFont->descent,"-180",4);
+      XDrawImageString(display,pix,gc,InXSize-3*FixFontWidth,InYSize-FixFont->descent,"180",3);
+      XDrawImageString(display,pix,gc,OffX+(InXSize-OffX)/2-3*FixFontWidth/2,InYSize-FixFont->descent,"0",1);
+   }
+   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+}
+
+void ShowGridHov(void)
+{
+   int jlon,jlat,x,y,len;
+   float dx,dy;
+   char Text[80];
+
+   /* Grid for Hovmoeller */
+
+   XSetForeground(display,gc,WhitePix);
+   XSetBackground(display,gc,BlackPix);
+   XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   dx = (InXSize - OffX) / 6.0;
+   for (jlon = 1 ; jlon < 6 ; ++jlon)
+   {
+      x = OffX + jlon * dx;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize-1);
+   }
+   dy = (InYSize - OffY) / 5.0; /* Every 5 days */
+   for (jlat = 1 ; jlat < 5 ; ++jlat)
+   {
+      y = OffY + jlat * dy;
+      XDrawLine(display,pix,gc,OffX,y,InXSize-1,y);
+   }
+   if (GridLabel)
+   {
+      XDrawImageString(display,pix,gc,OffX,InYSize-FixFont->descent,"0",1);
+      XDrawImageString(display,pix,gc,InXSize-3*FixFontWidth,InYSize-FixFont->descent,"360",3);
+      XDrawImageString(display,pix,gc,OffX+(InXSize-OffX)/2-3*FixFontWidth/2,InYSize-FixFont->descent,"180",3);
+      XDrawImageString(display,pix,gc,OffX,OffY+FixFontHeight-FixFont->descent,"t0",2);
+      XDrawImageString(display,pix,gc,OffX,OffY+2*InYSize/5+FixFontHeight/2-FixFont->descent,"t-2",3);
+      XDrawImageString(display,pix,gc,OffX,OffY+4*InYSize/5+FixFontHeight/2-FixFont->descent,"t-4",3);
+   }
+   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+}
+
+void ShowGridHovT(void)
+{
+   int jlon,jlat,x,y,len;
+   float dx,dy;
+   char Text[80];
+
+   /* Grid for Hovmoeller */
+
+   XSetForeground(display,gc,WhitePix);
+   XSetBackground(display,gc,BlackPix);
+   XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   dy = (InYSize - OffY) / 6.0;
+   for (jlat = 1 ; jlat < 6 ; ++jlat)
+   {
+      y = OffY + jlat * dy;
+      XDrawLine(display,pix,gc,OffX,y,InXSize-1,y);
+   }
+   dx = (InXSize - OffX) / 5.0; /* Every 5 days */
+   for (jlat = 1 ; jlat < 5 ; ++jlat)
+   {
+      x = OffX + jlat * dx;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize-1);
+   }
+   if (GridLabel)
+   {
+      XDrawImageString(display,pix,gc,OffX,OffY+FixFontHeight-FixFont->descent,"0",1);
+      XDrawImageString(display,pix,gc,OffX,OffY+(InYSize-OffY)/2+FixFontHeight/2-FixFont->descent,"180",3);
+      XDrawImageString(display,pix,gc,OffX,InYSize-FixFont->descent,"360",3);
+      XDrawImageString(display,pix,gc,InXSize-2*FixFontWidth,InYSize-FixFont->descent,"t0",2);
+      XDrawImageString(display,pix,gc,3*InXSize/5-3*FixFontWidth/2,InYSize-FixFont->descent,"t-2",3);
+      XDrawImageString(display,pix,gc,  InXSize/5-3*FixFontWidth/2,InYSize-FixFont->descent,"t-4",3);
+   }
+   XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+}
+
+void ShowGridPolar(void)
+{
+   int dx,dy,x,y,xh,yh,ox,oy;
+   XPoint pxy[3];
+
+   /* Grid for polar projection */
+
+   dx = (InXSize - OffX) / 2;
+   dy = (InYSize - OffY);
+   xh = dx / 2;
+   yh = dy / 2;
+   ox = dx / 3.414;
+   oy = dy / 3.414;
+
+   if (Grid)
+   {
+      XSetForeground(display,gc,WhitePix);
+      XSetBackground(display,gc,BlackPix);
+      XSetLineAttributes(display,gc,1,LineOnOffDash,CapButt,JoinRound);
+   
+      /* Northern Hemisphere */
+   
+      XDrawArc(display,pix,gc,OffX+dx/6,OffY+dy/6,2*dx/3,2*dy/3,0,360*64);
+      XDrawArc(display,pix,gc,OffX+dx/3,OffY+dy/3,dx/3,dy/3,0,360*64);
+   
+      XDrawLine(display,pix,gc,OffX,yh,InXSize,yh);
+      XDrawLine(display,pix,gc,OffX+xh,OffY,OffX+xh,InYSize);
+   
+      /* Southern Hemisphere */
+   
+      XDrawArc(display,pix,gc,OffX+7*dx/6,OffY+dy/6,2*dx/3,2*dy/3,0,360*64);
+      XDrawArc(display,pix,gc,OffX+4*dx/3,OffY+dy/3,dx/3,dy/3,0,360*64);
+   
+      x = OffX + dx + xh;
+      XDrawLine(display,pix,gc,x,OffY,x,InYSize);
+   
+      if (GridLabel)
+      {
+         x  = OffX + xh - FixFontWidth/2;
+         y  = OffY + yh + FixFontHeight/2 - FixFont->descent;
+         XDrawImageString(display,pix,gc,x,y,"N",1);
+         XDrawImageString(display,pix,gc,x+dx,y,"S",1);
+      }
+      XSetLineAttributes(display,gc,1,LineSolid,CapButt,JoinRound);
+   }
+
+   /* Octagon mask */
+
+   XSetForeground(display,gc,BlackPix);
+   pxy[0].x = pxy[1].x = OffX;
+   pxy[0].y = pxy[2].y = OffY;
+   pxy[1].y = OffY + oy;
+   pxy[2].x = OffX + ox;
+   XFillPolygon(display,pix,gc,pxy,3,Convex,CoordModeOrigin);
+   pxy[0].x = OffX + dx - ox;
+   pxy[1].x = OffX + dx;
+   pxy[2].x = OffX + dx + ox;
+   XFillPolygon(display,pix,gc,pxy,3,Convex,CoordModeOrigin);
+   pxy[0].x = InXSize - ox;
+   pxy[1].x = InXSize;
+   pxy[2].x = InXSize;
+   XFillPolygon(display,pix,gc,pxy,3,Convex,CoordModeOrigin);
+
+   pxy[0].x = pxy[1].x = OffX;
+   pxy[0].y = pxy[2].y = InYSize;
+   pxy[1].y = InYSize - oy;
+   pxy[2].x = OffX + ox;
+   XFillPolygon(display,pix,gc,pxy,3,Convex,CoordModeOrigin);
+   pxy[0].x = OffX + dx - ox;
+   pxy[1].x = OffX + dx;
+   pxy[2].x = OffX + dx + ox;
+   XFillPolygon(display,pix,gc,pxy,3,Convex,CoordModeOrigin);
+   pxy[0].x = InXSize - ox;
+   pxy[1].x = InXSize;
+   pxy[2].x = InXSize;
+   XFillPolygon(display,pix,gc,pxy,3,Convex,CoordModeOrigin);
+}
+
+
+void AutoPalette(int w, struct ColorStrip Strip[], REAL f[], int Dim)
+{
+   int i,nbands;
+   double fmin, fmax, frange, delta, fdelta, xdelta, Lo;
+
+   fmin = fmax = f[0];
+   for (i=0; i < Dim ; ++i)
+   {
+      if (fmin > f[i]) fmin = f[i];
+      if (fmax < f[i]) fmax = f[i];
+   }
+   frange = fmax - fmin;
+   Lo     = 0.0;
+   xdelta = 0.1;
+   if (frange > 1.0e-10)
+   {
+       delta  = frange / AUTOCOLORS;
+       if (delta > AutoDelta[w] / 1.4 && delta < 1.4 * AutoDelta[w])
+       {
+          xdelta = AutoXdelt[w];
+          delta  = AutoDelta[w];
+          Lo     = AutoLo[w];
+       }
+       else
+       {
+          fdelta = pow(10.0,rint(log10(delta)));
+          xdelta = fdelta;
+          nbands = frange / xdelta;
+          if (nbands < AUTOCOLORS / 2) xdelta = 0.5 * fdelta;
+          if (nbands > AUTOCOLORS    ) xdelta = 2.0 * fdelta;
+          nbands = frange / xdelta;
+          if (nbands > AUTOCOLORS    ) xdelta = 5.0 * fdelta;
+          Lo = xdelta * floor(fmin / xdelta);
+          AutoDelta[w] = delta;
+          AutoXdelt[w] = xdelta;
+          AutoLo[w]    = Lo;
+/*
+          if (Debug)
+          {
+             printf("Autopalette\n");
+             printf(" Range: %14.6e\n",frange);
+             printf(" delta: %14.6e\n",delta);
+             printf("fdelta: %14.6e\n",fdelta);
+             printf("xdelta: %14.6e\n",xdelta);
+          }
+*/
+       }
+   }
+   Strip[0].Lo = Lo;
+   for (i=0 ; i < AUTOCOLORS ; ++i)
+   {
+       Strip[i+1].Lo = Strip[i].Hi = Strip[i].Lo + xdelta;
+       // if (Debug) printf("Auto[%2d] = %10.4f - %10.4f\n",i,Strip[i].Lo,Strip[i].Hi);
+   }
+   return;
+}
+
+
+// Interface routine to model code in FORTRAN
+
+void guiput_(char *aname, float *array, int *dimx, int *dimy, int *dimz)
+{
+   int i,nb,nf;
+
+   if (Debug) printf("guiput(%s,%12.4e,%d,%d,%d)\n",
+                     aname,*array,*dimx,*dimy,*dimz);
+   nf = (*dimx) * (*dimz);
+   if (*dimy > 0) nf *= (*dimy);
+   else           nf *= 2;
+   nb = nf * sizeof(float);
+   for (i=0 ; i < NumArrays ; ++i)
+      if (!strcmp(aname,Array[i].Name)) break;
+   if (i == NumArrays)
+   {
+      ++NumArrays;
+      strcpy(Array[i].Name,aname);
+      Array[i].Data = FloatAlloc(nf,aname);
+      Array[i].DimX = *dimx;
+      Array[i].DimY = *dimy;
+      Array[i].DimZ = *dimz;
+      if (strcmp(aname,"GU") == 0) Uindex = i;
+      if (strcmp(aname,"GV") == 0) Vindex = i;
+   }
+   if (Array[i].Data) memcpy(Array[i].Data,array,nb);
+   Array[i].Flag = 1; // Data have changed
+}
+
+
+void guisend_(char *aname, float *array, int *dimx, int *dimy, int *dimz)
+{
+   int i,nb,nf;
+
+   nf = (*dimx) * (*dimz);
+   if (*dimy > 0) nf *= (*dimy);
+   else           nf *= 2;
+   nb = nf * sizeof(float);
+   for (i=0 ; i < NumArrays ; ++i)
+      if (!strcmp(aname,Array[i].Name)) break;
+   if (i == NumArrays)
+   {
+      ++NumArrays;
+      strcpy(Array[i].Name,aname);
+      Array[i].DimX = *dimx;
+      Array[i].DimY = *dimy;
+      Array[i].DimZ = *dimz;
+   }
+   Array[i].Data = array;
+   Array[i].Flag = 1; // Data have changed
+}
+
+
+// Do the plot
+
+void iso(int w,int PicType,REAL *field,int dimx,int dimy,int dimz,int pal)
+{
+   char Text[128];
+
+   int i,j,k,len,lens,xp,yp,status,x;
+   int y,dx,r,width,height;
+   INTXU border,depth;
+   REAL f,o,ra,rb;
+   int CapLines;
+   float *tspt;
+   XEvent WinEvent;
+   Window Rootwin,Child;
+
+   // if (Debug) printf("iso(%d,%s,%12.4e,%d,%d,%d,%d)\n",w,IsoNames[PicType],*field,dimx,dimy,dimz,pal);
+   if (Win[w] == 0) return;
+   win = w;
+
+   // At high frame rates (SkipFreq > 1) some types are redrawn
+   // at "SkipFreq" intervals
+
+   if (SkipFreq > 1 && (nstep % SkipFreq) != 0 && 
+      (PicType == ISOCS  || PicType == ISOHOR ||
+       PicType == MAPHOR || PicType == ISOCOL ||
+       PicType == ISOREC )) return;
+
+   XGetGeometry(display,Win[w],&Rootwin,&xp,&yp,&WinXSize,&WinYSize,
+		&border,&depth);
+   WinAtt[w].w = WinXSize;
+   WinAtt[w].h = WinYSize;
+   InXSize = WinXSize - OffX;
+   InYSize = WinYSize - OffY;
+
+   // Determine aspect ratio of window
+   // width = 2 * height is optimal (1.0)
+
+   if (InXSize > 2 * InYSize) // wide
+   {
+     arx = InXSize / (2.0 * InYSize);
+     ary = 1.0;
+   }
+   else // narrow
+   {
+     arx = 1.0;
+     ary = (2.0 * InYSize) / InXSize;
+   }
+
+   if (PicType != ISOTRA && PicType != MAPTRA) InYSize -= 20; // Room for colorbar
+   DimX  = dimx;
+   DimY  = dimy;
+   DimZ  = dimz;
+   if (DimY < 0) DimY = -DimY; // Get NTP1 for ISOSH
+   DimXY = DimX * DimY;
+   VGAX  = (InXSize-1.0) / (DimX-1.0);
+   if (DimY > 1) VGAY  = (InYSize-1.0) / (DimY-1.0);
+   else          VGAY  = 1.0;
+   Field = field;
+
+   if (PicType == ISOTRA || PicType == MAPTRA)
+   {
+      DimX  = dimx; // NLON
+      DimY  = dimy; // NLAT
+      DimZ  = dimz; // NLEV
+      DimXY = DimX * DimY;
+      VGAX  = (InXSize-1.0) / (DimX-1.0);
+      VGAY  = (InYSize-1.0) / (DimY-1.0);
+      if (MaxZ[w] < DimZ)
+      {
+         MaxZ[w]   = DimZ;
+         Indez[w]  = DimZ / 4;
+         SwitchIndez(w,0); // Initialize title
+      }
+   }
+
+   if (PicType == ISOREC || PicType == ISOHOR || PicType == MAPHOR)
+   {
+      DimX  = dimx; // NLON
+      DimY  = dimy; // NLAT
+      DimZ  = dimz; // NLEV
+      DimXY = DimX * DimY;
+      VGAX  = (InXSize-1.0) / (DimX-1.0);
+      VGAY  = (InYSize-1.0) / (DimY-1.0);
+      if (MaxZ[w] < DimZ)
+      {
+         MaxZ[w]   = DimZ;
+         Indez[w]  = DimZ / 4;
+         SwitchIndez(w,0); // Initialize title
+         TSdata[w] = FloatAlloc(DimXY,"ISOLON");
+      }
+      if (MapPro[w] == POLAR)
+      {
+         Field = TSdata[w];
+         lp2ps(field + Indez[w] * DimXY,Field);
+      }
+/*
+      else if (MapPro[w] == AZIMUTHAL)
+      {
+         Field = TSdata[w];
+         lp2az(field + Indez[w] * DimXY,Field,MapLR[w].l);
+      }
+*/
+      else Field = field + Indez[w] * DimXY;
+   }
+
+   if (PicType == ISOLON)
+   {
+      DimX  = dimx; // NLON
+      DimY  = dimz; // NLEV
+      DimZ  = dimy; // NLAT
+      DimXY = DimX * DimY;
+      VGAX  = (InXSize-1.0) / (DimX-1.0);
+      VGAY  = (InYSize-1.0) / (DimY-1.0);
+      if (!TSdata[w])
+      {
+         TSdata[w] = FloatAlloc(DimXY,"ISOLON");
+         MaxZ[w]   = DimZ;
+         Indez[w]  = DimZ / 4;
+         SwitchIndez(w,0); // Initialize title
+      }
+      Field = TSdata[w];
+      for (j=0,i=0,k=DimX*Indez[w] ; j < DimY ; ++j,i+=DimX,k+=DimX*DimZ)
+      {
+         memcpy(Field+i,field+k,DimX * sizeof(REAL)); // copy latitude
+      }
+   }
+
+   if (PicType == ISOHOV)
+   {
+      DimX  = dimx; // NLON
+      DimY  = DimT; // time
+      DimZ  = dimy; // NLAT
+      DimXY = DimX * DimY;
+      VGAX  = (InXSize-1.0) / (DimX-1.0);
+      VGAY  = (InYSize-1.0) / (DimY-1.0);
+      if (!TSdata[w])
+      {
+         TSdata[w] = FloatAlloc(DimXY,"ISOHOV");
+         MaxZ[w]   = DimZ;
+         Indez[w]  = DimZ / 4;
+         SwitchIndez(w,0); // Initialize title
+      }
+      Field = TSdata[w];
+      memmove(Field+DimX,Field,(DimXY-DimX) * sizeof(REAL)); // scroll array
+      memcpy(Field,field+Indez[w]*DimX,DimX * sizeof(REAL)); // add line
+   }
+
+   // Advance write pointer HovInx until end of DimX
+   // then scroll array and reset pointer
+
+   if (PicType == ISOTS)
+   {
+      DimX  = DimT; // time
+      DimY  = dimx; // # of variables
+      DimZ  = dimz;
+      DimXY = DimX * DimY;
+      VGAX  = (InXSize-1.0) / (DimX-1.0);
+      VGAY  = (InYSize-1.0) / (DimY-1.0);
+      if (!TSdata[w])
+      {
+         TSdata[w] = FloatAlloc(DimXY+DimX,"ISOTS");
+      }
+      tspt  = TSdata[w];
+      ++HovInx[w];
+      if (HovInx[w] >= DimX)
+      {
+          HovInx[w] = 0;
+          memmove(tspt,tspt+DimX,DimXY * sizeof(REAL)); // scroll array
+      }
+      for (i=HovInx[w]+DimX-1,j=0 ; j < DimY ; i+=DimX,++j)
+         tspt[i] = field[j];                                  // add column
+      Field = tspt+HovInx[w];
+   }
+
+   if (PicType == ISOCOL)
+   {
+      DimX  = DimT; // time
+      DimY  = dimx; // level
+      DimZ  = dimy; // clickable index
+      DimXY = DimX * DimY;
+      VGAX  = (InXSize-1.0) / (DimX-1.0);
+      VGAY  = (InYSize-1.0) / (DimY-1.0);
+      if (!TSdata[w])
+      {
+         TSdata[w] = FloatAlloc(DimXY+DimX,"ISOCOL");
+         MaxZ[w]   = DimZ;
+         Indez[w]  = DimZ / 2;
+         SwitchIndez(w,0); // Initialize title
+      }
+      tspt  = TSdata[w];
+      ++HovInx[w];
+      if (HovInx[w] >= DimX)
+      {
+          HovInx[w] = 0;
+          memmove(tspt,tspt+DimX,DimXY * sizeof(REAL)); // scroll array
+      }
+      for (i=HovInx[w]+DimX-1,j=0 ; j < DimY ; i+=DimX,++j)
+         tspt[i] = field[j+Indez[w]*DimY];                                  // add column
+      Field = tspt+HovInx[w];
+   }
+
+   if (DimX > FlagSize)
+   {
+      if (Flag) free(Flag);
+      Flag = IntAlloc(DimX,"Flag");
+      FlagSize = DimX;
+   }
+
+   if (PicType == ISOSH) pal = 1; // ISOSH has its own palette
+   if (pal < 1 || pal >= NUMPAL)
+   {
+      Cstrip = Autostrip;
+      AutoPalette(w,Cstrip,Field,DimXY);
+      Lines  = AUTOCOLORS;
+      // printf("Autopalette %d for Win %d\n",pal,w);
+   }
+   else
+   {
+      Cstrip = Pallet[pal];
+      Lines  = LineCo[pal];
+   }
+
+   SizeChanged = (WinPixMap[w].DimX != WinXSize || WinPixMap[w].DimY != WinYSize);
+   if (SizeChanged)
+   {
+      if (WinPixMap[w].Pix) XFreePixmap(display,WinPixMap[w].Pix);
+      WinPixMap[w].Pix = XCreatePixmap(display,Win[w],WinXSize,WinYSize,ScreenD);
+      if (Debug)
+         printf("CreatePixmap  %10x %6d bytes\n",
+               (unsigned int)WinPixMap[w].Pix,WinXSize*WinYSize);
+      WinPixMap[w].DimX = WinXSize;
+      WinPixMap[w].DimY = WinYSize;
+   }
+   pix = WinPixMap[w].Pix; /* Set current pixmap */
+
+   /* Draw colour bar */
+   
+   if ((SizeChanged || Cstrip == Autostrip) &&
+       (PicType == ISOCS  || PicType == ISOHOR ||
+       	PicType == ISOHOV || PicType == ISOLON ||
+        PicType == ISOCOL || PicType == MAPHOR ||
+        PicType == ISOREC ))
+   {
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,InYSize,WinXSize,WinYSize);
+
+      CapLines = WinXSize / (20 + 3 * FixFontWidth);
+      if (CapLines > Lines) CapLines = Lines;
+      for (i=0 ; i < CapLines ; ++i)
+      {
+         XSetForeground(display,gc,Cstrip[i].pixel);
+         XFillRectangle(display,pix,gc,OffX+5+i*(WinXSize-20)/(CapLines-1),
+			OffY+InYSize+5,10,10);
+         XSetForeground(display,gc,BlackPix);
+         XDrawRectangle(display,pix,gc,OffX+5+i*(WinXSize-20)/(CapLines-1),
+			OffY+InYSize+5,10,10);
+      }
+      XSetForeground(display,gc,WhitePix);
+      XSetBackground(display,gc,BlackPix);
+      rb = Cstrip[CapLines-2].Hi - Cstrip[0].Hi;
+      for (i=0 ; i < CapLines-1 ; ++i)
+      {
+	 Text[0] = 0;
+	 ra = Cstrip[i].Hi;
+	 j = ra;
+	 if (j > -1000 && j < 10000) sprintf(Text,"%d",j);
+         if (ra < 100.0 && ra > -9.99)
+         {
+            sprintf(Text,"%4.1f",ra);
+            if (!strcmp(Text+2,".0")) Text[2] = 0;
+         }
+	 if (ra < 10.0 && ra >= 0.0)
+         {
+            sprintf(Text,"%4.2f",ra);
+            if (!strcmp(Text+1,".00")) Text[1] = 0;
+         }
+         len    = strlen(Text);
+	 if (len)
+         {
+            width  = XTextWidth(FixFont,Text,len);
+            height = FixFont->ascent + FixFont->descent;
+            xp     = OffX + 10 + (i+0.5) * (WinXSize-20)/(CapLines-1) - width/2;
+            yp     = WinYSize - height + 10;
+            XDrawImageString(display,pix,gc,xp,yp,Text,len);
+	 }
+      }
+   }
+
+   /* Draw mode legend */
+   
+   if (SizeChanged && PicType == ISOSH)
+   {
+      dx = WinXSize / 23;
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,0,WinXSize,WinYSize);
+
+      XSetForeground(display,gc,LightGreen.pixel);
+      XSetBackground(display,gc,BlackPix);
+      for (i=0 ; i < 21 ; i+=2)
+      {
+         sprintf(Text,"%d",i);
+         len    = strlen(Text);
+         width  = XTextWidth(FixFont,Text,len);
+         height = FixFont->ascent + FixFont->descent;
+         xp     = dx + i * dx - width/2 - FixFontWidth/2 + 1;
+         yp     = FixFontHeight;
+         XDrawImageString(display,pix,gc,xp,yp,Text,len);
+      }
+      XSetForeground(display,gc,LightBlue.pixel);
+      for (i=0 ; i < 21 ; i+=2)
+      {
+         sprintf(Text,"%d",i);
+         len    = strlen(Text);
+         width  = XTextWidth(FixFont,Text,len);
+         height = FixFont->ascent + FixFont->descent;
+         xp     = WinXSize - width - 2;
+         yp     = 2 * FixFontHeight + i * dx;
+         if (yp+FixFont->descent > InYSize) break;
+         XDrawImageString(display,pix,gc,xp,yp,Text,len);
+      }
+      strcpy(Text,"n/m");
+      len    = strlen(Text);
+      width  = XTextWidth(FixFont,Text,len);
+      xp     = WinXSize - width - 2;
+      yp     = FixFontHeight;
+      XSetForeground(display,gc,WhitePix);
+      XDrawImageString(display,pix,gc,xp,yp,Text,len);
+      strcpy(Text,"High ");
+      len    = strlen(Text);
+      width  = XTextWidth(FixFont,Text,len);
+      xp     = WinXSize/2 - AMPLI_COLS * 10 - width;
+      yp     = WinYSize - FixFontHeight + 10;
+      r      = FixFontHeight-2;
+      XSetForeground(display,gc,WhitePix);
+      if (xp > 0) XDrawImageString(display,pix,gc,xp,yp,Text,len);
+      strcpy(Text," Low");
+      len    = strlen(Text);
+      width  = XTextWidth(FixFont,Text,len);
+      xp     = WinXSize/2 + AMPLI_COLS * 10;
+      if (xp + width < WinXSize) XDrawImageString(display,pix,gc,xp,yp,Text,len);
+      yp     = InYSize;
+      XDrawLine(display,pix,gc,OffX,yp,WinXSize,yp);
+      yp     = WinYSize - r -  FixFont->descent;
+
+      for (i=0 ; i < AMPLI_COLS ; ++i)
+      {
+         xp = WinXSize/2 - AMPLI_COLS * 10 + i * 20;
+         XSetForeground(display,gc,AmpliStrip[AMPLI_COLS-i-1].pixel);
+         XFillArc(display,pix,gc,xp,yp,r,r,0,360*64);
+      }
+   }
+
+   if (SizeChanged && PicType == ISOTS) /* Timeseries Caption */
+   {
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,InYSize,WinXSize,WinYSize);
+      XSetBackground(display,gc,BlackPix);
+
+      xp = FixFontWidth;
+      yp = WinYSize - FixFontHeight + 10;
+      for (j=0 ; j < DimY ; ++j)
+      {
+         if (TSName[j][0])
+         {
+            strcpy(Text,TSName[j]);
+            len    = strlen(Text);
+            width  = XTextWidth(FixFont,Text,len);
+            XSetForeground(display,gc,TSColor[j]);
+            XDrawImageString(display,pix,gc,xp,yp,Text,len);
+   	    xp += width;
+         }
+         if (TSubsc[j][0])
+         {
+            XSetFont(display, gc, SubFont->fid);
+            strcpy(Text,TSubsc[j]);
+            len    = strlen(Text);
+            width  = XTextWidth(SubFont,Text,len);
+            XSetForeground(display,gc,TSColor[j]);
+            XDrawImageString(display,pix,gc,xp,yp,Text,len);
+   	    xp += width;
+            XSetFont(display, gc, FixFont->fid);
+         }
+         xp += FixFontWidth;
+      }
+   }
+
+   if (SizeChanged && PicType == ISOTAB) /* Table Caption */
+   {
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,0,WinXSize,WinYSize);
+      XSetBackground(display,gc,BlackPix);
+   }
+
+   if (PicType == ISOTS) 
+   {
+      if (TSxp[w] == NULL) TSxp[w] = SizeAlloc(DimX * DimY , sizeof(XPoint),"TSxp");
+      if (Dmin[w] == NULL) Dmin[w] = FloatAlloc(DimY ,"Dmin");
+      if (Dmax[w] == NULL) Dmax[w] = FloatAlloc(DimY ,"Dmax");
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+
+      for (j=0 ; j < DimY ; ++j) Dmin[w][j] = Dmax[w][j] = field[j];
+      if (nstep > 2)
+      {
+         for (j=0 ; j < DimY ; ++j)
+         {
+            for (i=1 ; i < DimX ; ++i)
+            {
+               Dmin[w][j] = MIN(Dmin[w][j],Field[i+j*DimX]);
+               Dmax[w][j] = MAX(Dmax[w][j],Field[i+j*DimX]);
+            }
+         }
+      }
+
+      if (nstep > 2)
+      for (j=0 ; j < DimY ; ++j)
+      {
+         XSetForeground(display,gc,TSColor[j]);
+         o = Dmin[w][j];
+         if ((Dmax[w][j] - Dmin[w][j]) > 1.0e-20) f = (InYSize-2) / (Dmax[w][j] - Dmin[w][j]);
+         else f = 1.0;
+   
+         for (i=1 ; i < DimX ; ++i)
+         {
+            TSxp[w][i].x = VGAX * i;
+   	    TSxp[w][i].y = InYSize - 1 - f * (Field[i+j*DimX] - o);
+         }
+         XDrawLines(display,pix,gc,TSxp[w]+1,DimX-1,CoordModeOrigin);
+      }
+   }
+
+   if (PicType == ISOTAB) 
+   {
+      XSetForeground(display,gc,BlackPix);
+      XSetBackground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+      XSetFont(display, gc, BigFont->fid);
+      yp = BigFontHeight;
+      for (j=0 ; j < DimX ; ++j)
+      if (TSName[j][0])
+      {
+         XSetForeground(display,gc,TSColor[j]);
+         xp = BigFontWidth;
+         strcpy(Text,TSName[j]);
+         len = strlen(Text);
+         XDrawImageString(display,pix,gc,xp,yp,Text,len);
+   	 xp += XTextWidth(BigFont,Text,len);
+         if (TSubsc[j][0])
+         {
+            XSetFont(display, gc, FixFont->fid);
+            XDrawImageString(display,pix,gc,xp,yp,TSubsc[j],strlen(TSubsc[j]));
+            XSetFont(display, gc, BigFont->fid);
+         }
+         xp = 8 * BigFontWidth;
+         if (TSUnit[j][0])
+         {
+   	    sprintf(Text,"= %7.3f [%s]",field[j],TSUnit[j]);
+            if (TScale[j][0]) strcat(Text," 10");
+            len = strlen(Text);
+            XDrawImageString(display,pix,gc,xp,yp,Text,len);
+            if (TScale[j][0] > ' ')
+            {
+               lens = strlen(TScale[j]);
+               XSetFont(display, gc, FixFont->fid);
+               XDrawImageString(display,pix,gc,xp+len*BigFontWidth,yp-BigFontHeight+FixFontHeight,TScale[j],lens);
+               XSetFont(display, gc, BigFont->fid);
+            }
+         }
+   	 yp += BigFontHeight;
+      }
+      XSetFont(display, gc, FixFont->fid);
+   }
+
+   if (PicType == ISOTRA)
+   {
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+      if (SizeChanged) ClearTracer();
+      TracerPlot(w);
+   }
+   if (PicType == MAPTRA)
+   {
+      if (SizeChanged) ClearTracer();
+      if (MapHR.X)
+      {
+         if (MapPro[w] == AZIMUTHAL)
+         {
+            if (RedrawFlag[w] || MapLR[w].w != WinXSize || MapLR[w].h != InYSize ||
+               (nstep % rmui == 0 && MapLR[w].f != 0))
+            {
+               RedrawFlag[w] = 0;
+               MapLR[w].w    = WinXSize;
+               MapLR[w].h    = InYSize;
+               MapLR[w].l   += MapLR[w].r;
+               if (MapLR[w].l < -180.0) MapLR[w].l += 360.0;
+               if (MapLR[w].l >  180.0) MapLR[w].l -= 360.0;
+               AzimuthalImage(&MapHR,&MapLR[w]);
+            }
+         }
+         else
+         {
+            if (RedrawFlag[w] || MapLR[w].w != WinXSize || MapLR[w].h != InYSize)
+            {
+               RedrawFlag[w] = 0;
+               MapLR[w].w  = WinXSize;
+               MapLR[w].h  = InYSize;
+               if (MapPro[w] == 1) PolarImage(&MapHR,&MapLR[w]);
+               else                ScaleImage(&MapHR,&MapLR[w]);
+            }
+         }
+         XPutImage(display,pix,gc,MapLR[w].X,0,0,0,0,MapLR[w].w,MapLR[w].h);
+      }
+      else
+      {
+         XSetForeground(display,gc,BlackPix);
+         XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+      }
+      TracerPlot(w);
+   }
+
+   // Now perform the plotting of areas and lines for simple
+   // rectangles with no transformation/projection involved
+
+   if (PicType == ISOCS  || PicType == ISOHOR ||
+       PicType == ISOLON || PicType == ISOCOL ||
+       PicType == ISOREC )
+   {
+      XSetForeground(display,gc,BlackPix);
+      XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+      IsoAreas(Cstrip);
+      IsoLines(Cstrip,0);
+   }
+
+   // Plotting of azimuthal or polar projection
+
+   if (PicType == MAPHOR)
+   {
+      if (MapHR.X)
+      {
+         if (MapPro[w] == AZIMUTHAL)
+         {
+            if (RedrawFlag[w] || MapLR[w].w != WinXSize || MapLR[w].h != InYSize ||
+               (nstep % rmui == 0 && MapLR[w].f != 0))
+            {
+               RedrawFlag[w] = 0;
+               MapLR[w].w    = WinXSize;
+               MapLR[w].h    = InYSize;
+               MapLR[w].l   += MapLR[w].r;
+               if (MapLR[w].l < -180.0) MapLR[w].l += 360.0;
+               if (MapLR[w].l >  180.0) MapLR[w].l -= 360.0;
+               AzimuthalImage(&MapHR,&MapLR[w]);
+            }
+            XPutImage(display,pix,gc,MapLR[w].X,0,0,0,0,MapLR[w].w,MapLR[w].h);
+            MapLines(Cstrip,1);
+         }
+         else
+         {
+            if (RedrawFlag[w] || MapLR[w].w != WinXSize || MapLR[w].h != InYSize)
+            {
+               RedrawFlag[w] = 0;
+               MapLR[w].w  = WinXSize;
+               MapLR[w].h  = InYSize;
+               if (MapPro[w] == 1) PolarImage(&MapHR,&MapLR[w]);
+               else                ScaleImage(&MapHR,&MapLR[w]);
+            }
+            XPutImage(display,pix,gc,MapLR[w].X,0,0,0,0,MapLR[w].w,MapLR[w].h);
+            IsoLines(Cstrip,1);
+         }
+      }
+      else
+      {
+         XSetForeground(display,gc,BlackPix);
+         XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+         IsoLines(Cstrip,1);
+      }
+   }
+
+   // Hovmoeller diagram
+
+   if (PicType == ISOHOV)
+   {
+      IsoAreas(Cstrip);
+   }
+   
+   // amplitudes of coeeficients of spherical harmonics
+
+   if (PicType == ISOSH)
+   {
+      AmplitudePlot();     
+   }
+
+   if (Grid && PicType == ISOCS) ShowGridCS();
+   if (Grid && PicType == ISOLON) ShowGridLonsi();
+   if (Grid && PicType == ISOHOV && MapPro[w] == 0) ShowGridHov();
+   if (Grid && PicType == ISOHOV && MapPro[w] == 1) ShowGridHovT();
+   if (PicType == ISOHOR &&  MapPro[w] == 1) ShowGridPolar();
+   if (Grid && PicType == ISOHOR && MapPro[w] == 0) ShowGridCyl();
+   if (Grid && PicType == ISOCOL) ShowGridCol();
+
+   // copy drawn image into visible display
+
+   XCopyArea(display,pix,Win[w],gc,0,0,WinXSize,WinYSize,0,0);
+}
+
+
+/* ==================================================================== */
+/* iguistep - this function is called from the model for every timestep */
+/* ==================================================================== */
+
+int iguistep_(float pparcs[],int kdatim[])
+{
+   int i,j,w;               // Loop indices
+   struct timeval TimeVal;  // Retrieve time info
+
+   if (Debug) printf("iguistep(%12.2e,%d-%d-%d)\n",
+                     pparcs[0],kdatim[0],kdatim[1],kdatim[2]);
+   nstep++;
+   memcpy(ndatim,kdatim,sizeof(ndatim));
+   DeltaTime = ndatim[4] - LastMinute;
+   if (DeltaTime < 0) DeltaTime += 60;
+   if (DeltaTime ==0) DeltaTime  = 60;
+   LastMinute = ndatim[4];
+
+   // Compute frames per second every 20 calls
+
+   gettimeofday(&TimeVal,NULL);
+   LastSecond = ThisSecond;
+   ThisSecond = TimeVal.tv_sec;
+
+   if ((SecEvent = ThisSecond) > LastSecond)
+   {
+      fps      = nstep - LastStep;
+      LastStep = nstep;
+      rmui     = fps / rmuf;
+      if (rmui < 1) rmui = 1;
+   }
+
+   SkipFreq = 1 + fps / 30; // Reduce plot rate on fast cpu's
+   if (SkipFreq < 0 || SkipFreq > 10) SkipFreq = 0;
+
+   for (w=0 ; w < NumWin ; ++w)
+   {
+      for (j=0 ; j < NumArrays ; ++j)
+      {
+         if (!strcmp(WinAtt[w].array_name,Array[j].Name))
+         {
+            if (Array[j].Flag || RedrawFlag[w])
+            iso(w,WinAtt[w].Plot,Array[j].Data,Array[j].DimX,Array[j].DimY,
+			         Array[j].DimZ,WinAtt[w].Palette);
+         }
+      }
+   }
+
+   for (i=0 ; i < Parcs ; ++i) Parc[i].Val = pparcs[i];
+   ShowStep();
+   ShowParcs();
+   HandleEvents();
+   if (XCheckTypedWindowEvent(display,Cow,Expose,&CowEvent))
+      RedrawControlWindow();
+   for (i=0 ; i < Parcs ; ++i) pparcs[i] = Parc[i].Val;
+
+   XSync(display,1);
+   if (Shutdown && MRpid < 1) SaveConfig();
+   if (Debug) printf("iguistep returns %d\n",Shutdown);
+   return Shutdown;
+}
+
+int nresources_(double *ut, double *st, long *mem, long *par, long *paf,
+               long *swa, long *dr, long *dw)
+{
+   struct rusage ru;
+   getrusage(RUSAGE_SELF,&ru);
+   *ut = ru.ru_utime.tv_sec + 0.000001 * ru.ru_utime.tv_usec;
+   *st = ru.ru_stime.tv_sec + 0.000001 * ru.ru_stime.tv_usec;
+   *mem = ru.ru_maxrss;
+   *par = ru.ru_minflt;
+   *paf = ru.ru_majflt;
+   *swa = ru.ru_nswap;
+   *dr  = ru.ru_inblock;
+   *dw  = ru.ru_oublock;
+   return 1;
+}
+
+/* ------------------------------------------------ */
+/* Stub routines for Absoft Compiler and others,    */
+/* which require, that FORTRAN callable C-functions */
+/* are written in uppercase letters only            */
+/* ------------------------------------------------ */
+
+
+void INITGUI(int *model, int *debug, int *lats, int *mrpid, int *mrnum, char *plan)
+{
+   initgui_(model,debug,lats,mrpid,mrnum,plan);
+}
+
+void GUICLOSE(void)
+{
+   guiclose_();
+}
+
+int IGUISTEP(float pparcs[], int kdatim[])
+{
+   return iguistep_(pparcs,kdatim);
+}
+
+void GUIPUT(char *aname, float *array, int *dimx, int *dimy, int *dimz)
+{
+   guiput_(aname, array, dimx, dimy, dimz);
+}
+
+int NRESOURCES(double *ut, double *st, long *mem, long *par, long *paf,
+               long *swa, long *dr, long *dw)
+{
+   return nresources_(ut,st,mem,par,paf,swa,dr,dw);
+}
+
+/* ------------------------------------------------ */
+/* Stub routines for IBM Compiler and others,       */
+/* which require, that FORTRAN callable C-functions */
+/* are written in lowercase without underscore      */
+/* ------------------------------------------------ */
+
+
+void initgui(int *model, int *debug, int *lats, int *mrpid, int *mrnum, char *plan)
+{
+   initgui_(model,debug,lats,mrpid,mrnum,plan);
+}
+
+void guiclose(void)
+{
+   guiclose_();
+}
+
+int iguistep(float pparcs[], int kdatim[])
+{
+   return iguistep_(pparcs,kdatim);
+}
+
+void guiput(char *aname, float *array, int *dimx, int *dimy, int *dimz)
+{
+   guiput_(aname, array, dimx, dimy, dimz);
+}
+
+int iguinan_(double *p)
+{
+   return isnan(*p);
+}
+
+int nresources(double *ut, double *st, long *mem, long *par, long *paf,
+              long *swa, long *dr, long *dw)
+{
+   return nresources_(ut,st,mem,par,paf,swa,dr,dw);
+}
diff --git a/cat/src/guix11.c b/cat/src/guix11.c
index e198eb49347d71ebf13f3e4d19f89418f443179a..b08ec1d9ecf84f0e2a8b2e9382855efb2667f985 100644
--- a/cat/src/guix11.c
+++ b/cat/src/guix11.c
@@ -82,6 +82,7 @@ int Debug = 0; // set in initgui
 #define ISOROT 10
 #define MAPHOR 11
 #define MAPTRA 12
+#define LINE   13
 
 /* Models */
 
@@ -102,7 +103,8 @@ char *IsoNames[] =
    "ISOCOL",
    "ISOROT",
    "MAPHOR",
-   "MAPTRA"
+   "MAPTRA",
+   "LINE"
 };
 
 int IsoTypes = sizeof(IsoNames) / sizeof(char *);
@@ -301,8 +303,8 @@ REAL *TSdata[NUMWIN];
 REAL *Dmin[NUMWIN];
 REAL *Dmax[NUMWIN];
 REAL *SpeedScale;
-XPoint *TSxp[NUMWIN];
-
+XPoint *TSxp[NUMWIN];       // data for timeseries
+XPoint *LIxp[NUMWIN];       // data for line plots
 
 #define MAXPAR 16384
 float pax[MAXPAR];
@@ -2566,6 +2568,55 @@ void IsoLines(struct ColorStrip Strip[],int Colored)
    }
 }
 
+
+/* ======== */
+/* LinePlot */
+/* ======== */
+
+void LinePlot(int w)
+{
+   int i;
+   REAL zmin,zmax,zrange,zdelta,f;
+
+   // allocate space for plot data
+
+   if (LIxp[w] == NULL) LIxp[w] = SizeAlloc(DimX, sizeof(XPoint),"LIxp");
+
+   // compute minimum & maximum for auto scaling
+
+   zmin = zmax = Field[0];
+   for (i=1 ; i < DimX ; ++i)
+   {
+      zmin = MIN(zmin,Field[i]);
+      zmax = MAX(zmax,Field[i]);
+   }
+   zrange = zmax - zmin;
+   if (zrange < 1e-10) f = 1.0;
+   else                f = (InYSize-2) / zrange;
+
+   // scale plot data
+
+   for (i=0 ; i < DimX ; ++i)
+   {
+      LIxp[w]->x = VGAX * i;
+      LIxp[w]->y = InYSize - 1 - f * (Field[i] - zmin);
+   }
+
+   // fill plot area with black
+
+   XSetForeground(display,gc,BlackPix);
+   XFillRectangle(display,pix,gc,0,0,WinXSize,InYSize);
+
+   // draw data
+
+   XDrawLines(display,pix,gc,LIxp[w],DimX,CoordModeOrigin);
+}
+
+
+/* ======== */
+/* AziPoint */
+/* ======== */
+
 int AziPoint(int fpx, int fpy, int *x2, int *y2)
 {
    int xc,yc;
@@ -4599,6 +4650,13 @@ void iso(int w,int PicType,REAL *field,int dimx,int dimy,int dimz,int pal)
       AmplitudePlot();     
    }
 
+   // line plot
+
+   if (PicType == LINE)
+   {
+      LinePlot(w);     
+   }
+
    if (Grid && PicType == ISOCS) ShowGridCS();
    if (Grid && PicType == ISOLON) ShowGridLonsi();
    if (Grid && PicType == ISOHOV && MapPro[w] == 0) ShowGridHov();
diff --git a/most.c b/most.c
index 7c21d626e9a98a3a830c10ff5bb5c028785ec5e1..35e4fdd4cfeca94c949f3721191eefafc3b2818b 100644
--- a/most.c
+++ b/most.c
@@ -1054,6 +1054,8 @@ void InitNamelist(void)
    NL_r(CAT,"cat","AFORC"    ,  0.001);
    NL_r(CAT,"cat","TFORC"    ,  0.01);
    NL_i(CAT,"cat","NFORC"    ,  0);
+   NL_i(CAT,"cat","NGUIDBG"  ,  0);
+   NL_i(CAT,"cat","NPOST"    ,  0);
    NL_i(CAT,"cat","NSIM"     ,  0);
    NL_i(CAT,"cat","KFMIN"    ,  0);
    NL_i(CAT,"cat","KFMAX"    ,  8);