1 
2 /*
3  * Include ./configure's header file
4  */
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8 
9 /*
10  *   Simple GrADS GUI interface based on libsx. The script interpreter
11  *   Custom_GUI() is implemented in file "gsgui.c".
12  *
13  *   REVISION HISTORY:
14  *
15  *   22May97   da Silva   First alpha version.
16  *   09Jun97   da Silva   Fixed CB_Cmd which cause the command string
17  *                        to be destroyed on the first click;
18  *                        Fixed small bug on the CB_VAR window: now
19  *                        the user can type an expression with blanks.
20  *   10Jun97   da Silva   Added CmdWin() callback.
21  *   19Sep97   da Silva   Fixed small bug in CB_Display().
22  *   10Oct97   da Silva   Revised Default_GUI().
23  *
24  *   --
25  *   (c) 1997 by Arlindo da Silva
26  *
27  *   Permission is granted to any individual or institution to use,
28  *   modify, copy, or redistribute this software so long as it is not
29  *   sold for profit, and provided this notice is retained.
30  *
31  */
32 
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include <time.h>
39 
40 #include "X11/libsx/libsx.h"
41 #include "X11/libsx/freq.h"
42 #include "grads.h"
43 #include "gx.h"
44 
45 extern struct gacmn gcmn;
46 
47 #include "gagui.h"
48 
49 static char default_var[128];         /* default variable for display */
50 
51 static char last_path_open[512];      /* remember last path names */
52 static char last_path_sdfopen[512];
53 static char last_path_exec[512];
54 static char last_path_run[512];
55 
56 static Widget var_window;        /* window for variable selection */
57 static Widget file_window;       /* window for file selection */
58 static Widget expr_window;       /* window for variable selection */
59 static int hold_on = 0;          /* controls 'clear' before displaying */
60 
61 #define MAXROWS 256             /* for temporary mem aloocation */
62 #define MAXCOLS 256
63 
64 #define NCMD 64             /* Sixe of command buffer */
65 #define LCMD 132            /* Max length of command */
66 static int  CmdWinON = 0;              /* Make sure there is only one
67                                           Command Win up */
68 static char **CmdWinList;   /* Command buffer */
69 static Widget Cmd_window, CmdExpr_window, CmdList_window;
70 
71 /*---------------------------------------------------------------------*
72 
73 /*
74  * This is the GaGUI entry point. Return is thru the quit button.
75  *
76  */
77 
gagui_main(int argc,char ** argv)78 int gagui_main(int argc, char **argv)
79 {
80 
81 /*
82   static char *argv[] = { "GrADS", "-bg", "gray", NULL, NULL };
83   static int   argc = 3;
84 */
85 
86   char *path;
87 
88   if ( gcmn.batflg ) return 0;  /* batch mode */
89 
90   argc = OpenDisplay(argc, argv);
91   if (argc == FALSE)
92     return argc;
93 
94 /*
95   printf("Athena Widgets Support, (c) 1997 by Arlindo da Silva\n");
96   printf("Data Assimilation Office, NASA/GSFC\n\n");
97 */
98 
99   /* Default path for file loads */
100   strcpy(last_path_open,"./");
101   strcpy(last_path_sdfopen,"./");
102   strcpy(last_path_exec,"./");
103   strcpy(last_path_run,"./");
104   if ( path = getenv("GADATA") ) {
105        strcpy(last_path_open,path);
106        strcpy(last_path_sdfopen,path);
107   }
108   if ( path = getenv("GASCRP") ) {
109        strcpy(last_path_exec,path);
110        strcpy(last_path_run,path);
111   }
112   default_var[0] = '\0';
113 
114   /* Widget request on startup */
115   if ( path = getenv( "GAGUI" ) ) {
116 
117        /* Built in default GUI interface */
118        if ( !strcmp(path,"default") ) {
119           argc = Default_GUI(argc, argv, NULL);
120           if (argc == 0) exit(0);
121           printf("     <<< Click on the RED button for the 'ga>' prompt >>>\n\n");
122           MainLoop();
123 
124        /* Widget set from a script */
125        } else {
126          if(Custom_GUI(path)) return 1;
127          MainLoop();
128        }
129 
130   }
131 
132 }
133 
134 
135 /* List() - Allocates memory for character list */
List(int rows,int cols)136 char **List(int rows,int cols)
137 {
138   int  i;
139   char **p;
140 
141   /* Allocate pointers to rows */
142   p = ( char ** ) calloc ( rows, sizeof(char *) );
143   if(!p) {
144     printf("Error: cannot allocate memory for list (rows)\n");
145     return (char **)NULL;
146   }
147 
148   /* Allocate rows and set pointers to them */
149   for(i=0; i<rows; i++) {
150       p[i] = ( char * ) calloc ( cols, sizeof(char) );
151       if(!p[i]) {
152 	printf("Error: cannot allocate memory for list (cols)\n");
153 	return (char **)NULL;
154       }
155   }
156 
157   return (char **)p;
158 }
159 
160 /* Free_List() - De-allocates memory for character list */
Free_List(char ** list,int rows)161 void Free_List(char **list, int rows)
162 {
163    int i;
164    for(i=0;i<rows;i++) free((char *)list[i]);
165    free((char *)list);
166 }
167 
168 /*
169  * Return the directory component of a string or NULL if it's in
170  * the current directory.
171  */
dirname(char * str)172 char *dirname(char *str)
173 {
174   char *ptr, *tmp;
175 
176   ptr = strrchr(str, '/');
177   if (ptr == NULL)
178     return NULL;
179 
180   *ptr = '\0';
181   tmp = strdup(str);
182 
183   *ptr = '/';
184 
185   return tmp;
186 }
187 
188 
189 
190 /*
191  *  Default_GUI() - sets up default widget set.
192  */
193 
194 int
Default_GUI(int argc,char ** argv,void * data)195 Default_GUI(int argc, char **argv, void *data)
196 {
197   Widget  root, file, print, options, quit, reinit,prompt;
198   Widget  clear, hold, prev, play, next, dim, var;
199   char str[256];
200   int i, gold, blue, gray;
201 
202 /*
203   argc = OpenDisplay(argc, argv);
204   if (argc == FALSE)
205     return argc;
206 */
207 
208   sprintf (str, "GrADS Version " GRADS_VERSION "\n");
209   root = MakeLabel(str);
210 
211   file = MakeMenu ( "File" );
212          MakeMenuItem(file, "Open",            CB_Load,    "open");
213          MakeMenuItem(file, "SDF Open",        CB_Load,    "sdfopen");
214          MakeMenuItem(file, "XDF Open",        CB_Load,    "xdfopen");
215          MakeMenuItem(file, "File Selection ", CB_FileSel, NULL );
216          MakeMenuItem(file, "_______________", NULL,       NULL );
217          MakeMenuItem(file, "Exec",            CB_Load,    "exec");
218          MakeMenuItem(file, "Run",             CB_Load,    "run");
219          MakeMenuItem(file, "GUI",             CB_Load,    "gui");
220          MakeMenuItem(file, "_______________", NULL,       NULL );
221          MakeMenuItem(file, "Refresh",         CB_Cmd,     "  ");
222          MakeMenuItem(file, "Reinit",          CB_Cmd,     "reinit");
223          MakeMenuItem(file, "Exit",            CB_Exit,    NULL );
224 
225   print = MakeMenu ( "Print" );
226           MakeMenuItem(print, "Print",         CB_Cmd,     "print");
227           MakeMenuItem(print, "Enable  Print", CB_Load,    "enable print");
228           MakeMenuItem(print, "Disable Print", CB_Cmd,     "disabled print");
229 
230   options = MakeMenu ( "Options" );
231             MakeMenuItem(options, "Shaded",      CB_Cmd, "set gxout shaded" );
232             MakeMenuItem(options, "Contour",     CB_Cmd, "set gxout contour" );
233             MakeMenuItem(options, "Grid Fill",   CB_Cmd, "set gxout grfill" );
234             MakeMenuItem(options, "Grid Values", CB_Cmd, "set gxout grid" );
235             MakeMenuItem(options, "Vector",      CB_Cmd, "set gxout vector" );
236             MakeMenuItem(options, "Streamlines", CB_Cmd, "set gxout stream" );
237             MakeMenuItem(options, "Bar Chart",   CB_Cmd, "set gxout bar" );
238             MakeMenuItem(options, "Line Plot",   CB_Cmd, "set gxout line" );
239             MakeMenuItem(options, "Wind Barbs",  CB_Cmd, "set gxout  barb" );
240             MakeMenuItem(options, "_______________",  NULL, NULL );
241             MakeMenuItem(options, "Contour Interval",  CB_CmdStr, "set cint" );
242             MakeMenuItem(options, "Draw Title", CB_CmdStr, "draw title " );
243             MakeMenuItem(options, "Color Bar",  CB_Cmd, "run cbarn" );
244 
245   reinit  = MakeButton("Reinit",  CB_Cmd,     "reinit" );
246   clear  = MakeButton("Clear",  CB_Cmd,     "clear" );
247   quit   = MakeButton("Quit",   CB_Cmd,     "quit"  );
248   prompt = MakeButton("ga>",  CB_CmdWin, NULL );
249 
250   dim    = MakeMenu("Dim");
251            MakeMenuItem(dim, "Longitude", CB_CmdStr, "set lon " );
252            MakeMenuItem(dim, "Latitude",  CB_CmdStr, "set lat " );
253            MakeMenuItem(dim, "Level",     CB_CmdStr, "set lev " );
254            MakeMenuItem(dim, "Time",      CB_CmdStr, "set time " );
255            MakeMenuItem(dim, "_________", NULL,      NULL );
256            MakeMenuItem(dim, "x",         CB_CmdStr, "set x " );
257            MakeMenuItem(dim, "y",         CB_CmdStr, "set y " );
258            MakeMenuItem(dim, "z",         CB_CmdStr, "set z " );
259            MakeMenuItem(dim, "t",         CB_CmdStr, "set t " );
260 
261   var    = MakeButton("Var",    CB_VarSel,  NULL );
262   hold   = MakeToggle("Hold",   FALSE, NULL, CB_Toggle,  "hold" );
263   prev   = MakeButton("<<",   CB_Display, "<<" );
264   play   = MakeButton("Display",   CB_Display, "DISPLAY" );
265   next   = MakeButton(">>",   CB_Display, ">>" );
266 
267 
268   /* First row */
269   SetWidgetPos(file,    PLACE_UNDER, root, NO_CARE, NULL);
270   SetWidgetPos(print,   PLACE_UNDER, root, PLACE_RIGHT, file );
271   SetWidgetPos(options, PLACE_UNDER, root, PLACE_RIGHT, print );
272   SetWidgetPos(dim,     PLACE_UNDER, root, PLACE_RIGHT, options );
273   SetWidgetPos(reinit,     PLACE_UNDER, root, PLACE_RIGHT, dim);
274   SetWidgetPos(prompt,  PLACE_UNDER, root, PLACE_RIGHT, reinit );
275 
276   /* Second row */
277   SetWidgetPos(hold,   PLACE_UNDER, file, NO_CARE, NULL);
278   SetWidgetPos(var,   PLACE_UNDER, file, PLACE_RIGHT, hold );
279   SetWidgetPos(prev,  PLACE_UNDER, file, PLACE_RIGHT, var );
280   SetWidgetPos(play,  PLACE_UNDER, file, PLACE_RIGHT, prev );
281   SetWidgetPos(next,  PLACE_UNDER, file, PLACE_RIGHT, play );
282   SetWidgetPos(clear, PLACE_UNDER, file, PLACE_RIGHT, next );
283   SetWidgetPos(quit,  PLACE_UNDER, file, PLACE_RIGHT, clear );
284 
285   ShowDisplay();
286 
287   GetStandardColors();
288   gold = GetNamedColor("gold");
289   blue = GetNamedColor("LightSkyBlue");
290   gray = GetNamedColor("gray");
291 
292   /* Color of widgets */
293   SetFgColor(root,RED);
294   SetFgColor(prompt,YELLOW);
295   SetBgColor(prompt,RED);
296 
297   SetBgColor(file,blue);
298   SetBgColor(print,blue);
299   SetBgColor(options,blue);
300   SetBgColor(dim,blue);
301 
302   SetBgColor(reinit,gray);
303   SetBgColor(var,gray);
304   SetBgColor(hold,gray);
305   SetBgColor(clear,gray);
306   SetBgColor(quit,gray);
307 
308   SetBgColor(prev,gold);
309   SetBgColor(play,gold);
310   SetBgColor(next,gold);
311 
312   return argc;
313 }
314 
315 /*
316  * CB_Open() - Callback function for (sdf) opening a file.  The opened file
317  *             becomes the default and the user is asked to select a
318  *             variable from the file. Unlike CB_Load(), the user must
319  *             provide the file name.
320  *
321  */
CB_Open(Widget w,void * data)322 void CB_Open(Widget w, void *data)
323 {
324 
325   char cmd[1024];
326   int  rc;
327 
328   printf("%s\n", data);
329   gcmn.sig = 0;
330   strncpy(cmd,data,1024);
331   rc = gacmd(cmd,&gcmn,0);
332   if(rc) Beep();
333   else if (cmpwrd("open",data)||cmpwrd("sdfopen",data))
334     {
335       sprintf(cmd,"set dfile %d", gcmn.fnum);
336       gcmn.sig = 0;
337       gacmd(cmd,&gcmn,0);  /* new file becomes default */
338       CB_VarSel(w, data);
339     }
340 
341 }
342 
343 /*
344  * CB_Load() - Callback function for the load button.  This just calls
345  *          GetFile() to get a file name. In case of "open" or "sdfopen",
346  *          the file becomes the default and the user is asked to select a
347  *          variable from this file.
348  */
CB_Load(Widget w,void * data)349 void CB_Load(Widget w, void *data)
350 {
351   char *fname, *dname, *last_path, cmd[1024];
352   int i,rc;
353 
354   if(strstr(data,"open"))         last_path = last_path_open;
355   else if(strstr(data,"sdfopen")) last_path = last_path_sdfopen;
356   else if(strstr(data,"exec"))    last_path = last_path_exec;
357   else if(strstr(data,"run"))     last_path = last_path_run;
358   else                            last_path = NULL;
359   fname = GetFile(last_path);
360 
361   if(fname)
362     {
363 
364     /* save retrieved directory name for next time */
365     dname = dirname(fname);
366     if(strstr(data,"open"))           strcpy(last_path_open,dname);
367     else if(strstr(data,"sdfopen"))   strcpy(last_path_sdfopen,dname);
368     else if(strstr(data,"exec"))      strcpy(last_path_exec,dname);
369     else if(strstr(data,"run"))       strcpy(last_path_run,dname);
370     if(dname) free(dname);
371 
372     sprintf(cmd,"%s %s", data, fname);
373     printf("%s\n", cmd);
374     gcmn.sig = 0;
375     rc = gacmd(cmd,&gcmn,0);
376     if(rc) Beep();
377     else if (cmpwrd("open",cmd)||cmpwrd("sdfopen",cmd))
378       {
379         sprintf(cmd,"set dfile %d", gcmn.fnum);
380         gcmn.sig = 0;
381         gacmd(cmd,&gcmn,0);  /* new file becomes default */
382 	CB_VarSel(w, data);
383       }
384 
385     free(fname);
386     }
387   else {
388     printf("%s cancelled\n", data);
389     Beep();
390   }
391 
392 }
393 
394 
395 /*
396  * CB_Cmd() - Callback funtion for a generic grads command  button.
397  */
CB_Cmd(Widget w,void * data)398 void CB_Cmd(Widget w, void *data)
399 {
400 
401     char cmd[1024];   /* temp space */
402     int rc;
403     if(data) {
404       gcmn.sig = 0;
405       strncpy(cmd,data,1024); /* need this or data will be overitten */
406       printf("%s\n", cmd);
407       rc=gacmd(cmd,&gcmn,0);
408       if(rc<0) {
409         if(GetYesNo("About to exit GrADS. Really?") == TRUE ) {
410 	  gxend();
411 	  exit(0);  /* not sure if needed */
412 	}
413       }
414       if(rc) Beep();
415     } else {
416       Beep();
417       printf("\n    ***** GUI option not implemented yet *****\n\n");
418     }
419 }
420 
421 
422 /*
423  *  CB_CmdLine() - Callback funtion for the command line button.
424  */
CB_CmdLine(Widget w,void * data)425 void CB_CmdLine(Widget w, void *data)
426 {
427 
428   char cmd[1024];
429   int rc=0;
430 
431   printf("\n     <<< Enter '.' to leave the command line interface >>>\n\n");
432 
433   while (rc>-1) {
434 #if READLINE == 1
435     nxrdln(&cmd[0],"ga->> ");
436 #else
437     nxtcmd(&cmd[0],"ga>>");
438 #endif
439     if ( cmd[0] == '.' )
440     {
441        printf("     <<< Click on the RED button for the 'ga>' prompt >>>\n\n");
442        return;
443     }
444     gcmn.sig = 0;
445     rc = gacmd(cmd,&gcmn,0);
446     /*    if(rc<0)
447        if(GetYesNo("About to exit GrADS. Really?") == FALSE ) rc=0;
448        */   /* Command liners know what they are doing ... */
449   }
450   gxend();
451   exit(0);  /* not sure if needed */
452 
453 }
454 
455 
456 /*
457  * CB_VarSel() - Callback for selecting a variable.
458  *
459  */
CB_VarSel(Widget W,void * data)460 void CB_VarSel(Widget W, void *data)
461 {
462    Widget w[8];
463    struct gacmn *pcm;
464    struct gafile *pfi;
465    struct gavar *pvar;
466    int i;
467    char **item_list, *var, tmp[MAXROWS];
468 
469    /* Make Variable List from GrADS data structures */
470    pcm = &gcmn;
471    if (pcm->pfi1==NULL) {
472       Beep();
473       printf("No Files Open\n");
474       return;
475    }
476    pfi = pcm->pfid;
477    pvar = pfi->pvar1;
478    item_list = (char **) List(pfi->vnum+1,MAXCOLS);
479    if(!item_list) return;
480    for (i=0;i<pfi->vnum;i++) {
481      /*      printf ("    %s %i %i %s\n",
482               pvar->abbrv,pvar->levels,pvar->units[0],pvar->varnm);
483 	      */
484       /* item_list[i] = pvar->abbrv; */
485       sprintf(item_list[i], "%12.12s  %3i  %s",
486               pvar->abbrv, pvar->levels, pvar->varnm);
487       pvar++;
488 
489     }
490    item_list[pfi->vnum]=(char *)NULL; /* terminate list */
491 
492 
493     /* Creates widgets, etc... */
494   var_window = MakeWindow("Select a Variable", SAME_DISPLAY, EXCLUSIVE_WINDOW);
495 
496   w[0]  = MakeLabel(pfi->title);
497   w[2]  = MakeScrollList(item_list, 500, 250, (void *)CB_VarList, item_list);
498   w[3]  = MakeLabel("GrADS Expression: ");
499   w[4]  = MakeStringEntry("", 300, (void *)CB_VarStr,         &item_list);
500   expr_window = w[4];
501   w[5]  = MakeButton("OK",         (void *)CB_VarOK,           NULL);
502   w[6]  = MakeLabel("Click on a Variable from the List or Enter an Expression");
503   w[7]  = MakeButton("Cancel",     (void *)CB_VarCancel,        &item_list);
504 
505   SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE,     NULL);
506   SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE,     NULL);
507   SetWidgetPos(w[4], PLACE_UNDER, w[2], PLACE_RIGHT, w[3]);
508   SetWidgetPos(w[5], PLACE_UNDER, w[3], NO_CARE,     NULL);
509   SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]);
510   SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]);
511 
512   ShowDisplay();
513   SetFgColor(w[0],BLUE);
514   SetFgColor(w[6],RED);
515 
516 
517   if(default_var[0]) var = default_var;
518   else {
519          strcpy(tmp,item_list[0]);
520 	 var = strtok(tmp," ");
521   }
522   SetStringEntry(expr_window, var);
523 
524   MainLoop();
525 
526   SetCurrentWindow(ORIGINAL_WINDOW);
527 
528   Free_List(item_list,pfi->vnum+1);
529 
530 }
531 
532 
533 /*
534  * CB_VarList() - Callback routine for Clicking on variable list button
535  */
536 
537 
CB_VarList(Widget w,char * str,int index,void * data)538 void CB_VarList(Widget w, char *str, int index, void *data)
539 {
540   char *var, cmd[1024];
541   var = strtok(str," ");
542   strcpy(default_var,var);
543   SetCurrentWindow(var_window);
544   CloseWindow();
545   if(!hold_on) CB_Cmd(w,"clear");
546   sprintf(cmd,"display %s", default_var);
547   CB_Cmd(w,cmd);  /* display the variable */
548 }
549 
CB_VarStr(Widget w,char * str,int index,void * data)550 void CB_VarStr(Widget w, char *str, int index, void *data)
551 {
552   char cmd[1024];
553   strcpy(default_var,str);
554   SetCurrentWindow(var_window);
555   CloseWindow();
556   SyncDisplay();
557   if(!hold_on) CB_Cmd(w,"clear");
558   sprintf(cmd,"display %s", default_var);
559   CB_Cmd(w,cmd);  /* display the variable */
560 }
561 
CB_VarOK(Widget w,void * data)562 void CB_VarOK(Widget w, void *data)
563 {
564    int index=1;
565    char *str, *tmp;
566    str = GetStringEntry(expr_window);
567    if(str==NULL) {
568      Beep();
569      return;
570    }
571    CB_VarStr(w, str, index, data);
572    if(str!=NULL) free(str);
573 }
574 
CB_VarCancel(Widget w,void * data)575 void CB_VarCancel(Widget w, void *data)
576 {
577   SetCurrentWindow(var_window);
578   CloseWindow();
579   Beep();
580   printf("Variable selection cancelled\n");
581   return;
582 
583 }
584 
585 /*-----------------------------------------------------------------------*/
586 
587 /*
588  * CB_CmdWin() - Callback for a command window.
589  *
590  */
CB_CmdWin(Widget W,void * data)591 void CB_CmdWin(Widget W, void *data)
592 {
593    Widget w[8];
594    int i;
595 
596    if(CmdWinON) {
597      Beep();
598      printf("Error: Command window already up!\n");
599      return;
600    }
601 
602    /* Initialize Command Win buffer */
603    CmdWinList = (char **) List(NCMD+1,LCMD);
604    if(!CmdWinList) return;
605    for(i=0;i<NCMD;i++) CmdWinList[i][0] = '\0';
606    CmdWinList[NCMD] = (char *) NULL;
607    strncpy(CmdWinList[0], "clear",             LCMD);
608    strncpy(CmdWinList[1], "reinit",            LCMD);
609    strncpy(CmdWinList[2], "set gxout shaded",  LCMD);
610    strncpy(CmdWinList[3], "set gxout contour", LCMD);
611    strncpy(CmdWinList[4], "print",             LCMD);
612    strncpy(CmdWinList[5], "quit",              LCMD);
613 
614 
615     /* Creates widgets, etc... */
616   Cmd_window = MakeWindow("GrADS Command Window", SAME_DISPLAY,
617                            NONEXCLUSIVE_WINDOW);
618 
619   w[0]  = MakeLabel("GrADS Command Window");
620   w[1]  = MakeLabel("ga> ");
621   w[2]  = MakeStringEntry("", 450, (void *)CB_CmdWinStr, NULL);
622   CmdExpr_window = w[2];
623 
624   w[3]  = MakeScrollList(CmdWinList, 500, 200, (void *)CB_CmdWinList,
625                          CmdWinList);
626   CmdList_window = w[3];
627   w[4]  = MakeButton("OK",    (void *)CB_CmdWinOK,          NULL);
628   w[5]  = MakeButton("Clear",  (void *)CB_CmdWinClear,  NULL);
629   w[6]  = MakeButton("Classic Cmd Line",   (void *)CB_CmdLine,  NULL);
630   w[7]  = MakeButton("Quit",  (void *)CB_Cmd,  "quit");
631 
632   SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE,     NULL);
633   SetWidgetPos(w[2], PLACE_UNDER, w[0], PLACE_RIGHT, w[1]);
634   SetWidgetPos(w[3], PLACE_UNDER, w[1], NO_CARE,     NULL);
635   SetWidgetPos(w[4], PLACE_UNDER, w[3], NO_CARE,     NULL);
636   SetWidgetPos(w[5], PLACE_UNDER, w[3], PLACE_RIGHT, w[4]);
637   SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]);
638   SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]);
639 
640   ShowDisplay();
641 
642   SetFgColor(w[0],BLUE);
643   SetFgColor(w[1],YELLOW);
644   SetBgColor(w[1],RED);
645   SetFgColor(w[4],BLUE);
646   SetFgColor(w[5],BLUE);
647   SetFgColor(w[6],BLUE);
648   SetFgColor(w[7],BLUE);
649 
650   CmdWinON = 1;
651 
652 }
653 
654 
Add_CmdList(char * cmd)655 void Add_CmdList( char *cmd )
656 {
657   int i;
658   char *tmp;
659   tmp = CmdWinList[NCMD-1];
660   for(i=NCMD-1;i>0;i--) CmdWinList[i] = CmdWinList[i-1];
661   CmdWinList[0] = tmp;
662   strncpy(CmdWinList[0],cmd,LCMD);
663   ChangeScrollList(CmdList_window, CmdWinList);
664 }
665 
CB_CmdWinList(Widget w,char * str,int index,void * data)666 void CB_CmdWinList(Widget w, char *str, int index, void *data)
667 {
668   static time_t cur_click, last_click=0, tloc=0;
669   float tdiff;
670   char cmd[1024];
671 
672 
673   cur_click = time(&tloc);
674   tdiff = (float)(cur_click - last_click);
675   strncpy(cmd,str,1024);
676   if(tdiff > 1. )  /* not a double click */
677    {
678      last_click = cur_click;
679      SetStringEntry(CmdExpr_window, cmd );
680    }
681    else {
682      CB_Cmd(w,cmd);
683      Add_CmdList(cmd);
684      SetStringEntry(CmdExpr_window, " " );
685      last_click = 0;
686    }
687 
688 }
689 
CB_CmdWinStr(Widget w,char * str,int index,void * data)690 void CB_CmdWinStr(Widget w, char *str, int index, void *data)
691 {
692   char cmd[1024];
693   strncpy(cmd,str,1024);
694   CB_Cmd(w,cmd);
695   Add_CmdList(cmd);
696   SetStringEntry(CmdExpr_window, " " );
697 }
698 
CB_CmdWinClear(Widget w,void * data)699 void CB_CmdWinClear(Widget w, void *data)
700 {
701   char cmd[1024] = "clear";
702   Add_CmdList(cmd);
703   CB_Cmd(w,cmd);
704   SetStringEntry(CmdExpr_window, " " );
705 }
706 
CB_CmdWinOK(Widget w,void * data)707 void CB_CmdWinOK(Widget w, void *data)
708 {
709    int index=1;
710    char *str;
711    str = GetStringEntry(CmdExpr_window);
712    if(str==NULL) {
713      Beep();
714      return;
715    }
716    CB_CmdWinStr(w, str, index, data);
717    if(str!=NULL) free(str);
718 }
719 
CB_CmdWinDone(Widget w,void * data)720 void CB_CmdWinDone(Widget w, void *data)
721 {
722   SetCurrentWindow(Cmd_window);
723   CloseWindow();
724   printf("Command Window closed\n");
725   CmdWinON = 0;
726   Free_List(CmdWinList,NCMD+1);
727   return;
728 }
729 
730 
731 /*-----------------------------------------------------------------------*/
732 
733 /*
734  * CB_Display() - Callback function for displaying the default variable.
735  *
736  */
737 
CB_Display(Widget w,void * data)738 void CB_Display(Widget w, void *data)
739 {
740 
741     struct gacmn *pcm;
742     struct gafile *pfi;
743     int  rc, t, tbeg, tend, tlast;
744     int  v1, v2;
745     char cmd[256];
746 
747     /* Any file open? */
748     pcm = &gcmn;
749     if (pcm->pfi1==NULL) {
750        Beep();
751        printf("No Files Open\n");
752        return;
753     }
754     pfi = pcm->pfid;
755 
756     /* Default variable? */
757     if(!default_var[0]) {
758       Beep();
759       printf("No default variable\n");
760       return;
761     }
762 
763 
764     /* Just Display current variable */
765     if ( strstr(data,"display") || strstr(data,"DISPLAY") ) {
766       if(!hold_on) CB_Cmd(w,"clear");
767       sprintf(cmd,"display %s", default_var );
768       CB_Cmd(w,cmd);
769       return;
770     }
771 
772 
773     /* Advance time or animate... */
774 
775     v1 = (int) t2gr(pfi->abvals[3],&(pcm->tmin));
776     v2 = (int) t2gr(pfi->abvals[3],&(pcm->tmax));
777     tlast = pfi->dnum[3];
778 
779     /* If dimenions are not varying ... */
780     if ( v1 == v2 ) {
781 
782       if ( strstr(data,"<<") ) {
783         v1--;
784 	tbeg = v1;
785 	tend = tbeg;
786       }
787       else if ( strstr(data,">>") ) {
788         v1++;
789 	tbeg = v1;
790 	tend = tbeg;
791       }
792       else if ( strstr(data,"PLAY") ) {
793 	tbeg = v1;
794 	tend = tlast;
795       }
796 
797       /* time dim is varying, keep it */
798     } else {
799       tbeg = v1;
800       tend = v2;
801     }
802 
803     /* make sure all is within range */
804     if(tbeg<1)      tbeg  = 1;
805     if(tbeg>tlast)  tbeg  = tlast;
806     if(tend<1)      tend  = 1;
807     if(tend>tlast)  tend = tlast;
808 
809     /* Set time range and display variable */
810     sprintf(cmd,"set t %d %d", tbeg, tend);
811     CB_Cmd(w,cmd);
812     if(!hold_on) CB_Cmd(w,"clear");
813 
814     /* Display the variable: one frame or (continuous) animation */
815     sprintf(cmd,"display %s", default_var );
816     CB_Cmd(w,cmd);
817 
818     /* If we setup a time range for PLAY, restore time to what it
819        was before the animation. */
820     if(v1==v2&&strstr(data,"PLAY")) {
821        sprintf(cmd,"set t %d %d", v1, v1);
822        CB_Cmd(w,cmd);
823     }
824 
825 }
826 
827 
828 /*
829  * CB_Toggle() - Callback funtion for a generic toggle button.
830  */
CB_Toggle(Widget w,void * data)831 void CB_Toggle(Widget w, void *data)
832 {
833 
834   if ( strstr(data,"hold") ) {
835        hold_on = 1 - hold_on;
836        if(hold_on) printf("Hold  ON: no clear screen before display\n");
837        else        printf("Hold OFF: clear screen before display\n");
838   }
839 }
840 
841 
842 /*
843  * CB_FileSel() - Callback for selecting an already open file.
844  *
845  */
CB_FileSel(Widget W,void * data)846 void CB_FileSel(Widget W, void *data)
847 {
848    Widget w[8];
849    struct gacmn *pcm;
850    struct gafile *pfi;
851    int j;
852    char **item_list;
853 
854    /* Make File List from GrADS data structures */
855    pcm = &gcmn;
856    if (pcm->pfi1==NULL) {
857       Beep();
858       printf("No Files Open\n");
859       return;
860    } else {
861       pfi = pcm->pfi1;
862       item_list = (char **) List(MAXROWS,MAXCOLS);
863       j = 0;
864       while (pfi!=NULL && j<MAXROWS-1) {
865         sprintf(item_list[j],"%12s  %s", pfi->name, pfi->title);
866         pfi = pfi->pforw;
867         j++;
868       }
869       item_list[j] = (char *) NULL;
870     }
871 
872   /* Creates widgets, etc... */
873   file_window = MakeWindow("Select a File", SAME_DISPLAY, EXCLUSIVE_WINDOW);
874 
875   w[0]  = MakeLabel("Files Open:");
876   w[2]  = MakeScrollList(item_list, 500, 250, (void *)CB_FileList, item_list);
877   w[6]  = MakeLabel("Click on a File");
878 
879   SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE,     NULL);
880   SetWidgetPos(w[6], PLACE_UNDER, w[2], NO_CARE,     NULL);
881 
882   ShowDisplay();
883   SetFgColor(w[0],BLUE);
884   SetFgColor(w[6],RED);
885 
886   MainLoop();
887 
888   SetCurrentWindow(ORIGINAL_WINDOW);
889 
890   Free_List(item_list,MAXROWS);
891 
892 }
893 
894 
895 /*
896  * CB_FileList() - Callback routine for file list.
897  */
898 
899 
CB_FileList(Widget w,char * str,int index,void * data)900 void CB_FileList(Widget w, char *str, int index, void *data)
901 {
902   char cmd[1024];
903   SetCurrentWindow(file_window);
904   CloseWindow();
905   sprintf(cmd,"set dfile %d", index+1);
906   CB_Cmd(w,cmd);  /* set file as default */
907 }
908 
909 
910 /*
911  * CB_CmdStr() - Callback funtion for a generic grads command with user input.
912  */
CB_CmdStr(Widget w,void * data)913 void CB_CmdStr(Widget w, void *data)
914 {
915     char cmd[1024], *str;
916 
917     str = GetString(data, NULL);
918     if(str!=NULL) {
919       sprintf(cmd,"%s %s", data, str);
920       CB_Cmd(w,cmd);
921       free(str);
922     }
923 
924 }
925 
926 /*
927  * CB_Exit() - Exits GUI, well... fake it.
928  *             NOTE: not working properly yet.
929  */
930 
CB_Exit(Widget w,void * data)931 void CB_Exit(Widget w, void *data)
932 {
933 
934 /*  if(GetYesNo("About to exit Graphical User Interface. Really?") == FALSE)
935      return;
936 */
937 
938   /* Get rid of GUI window */
939   CloseWindow();
940   SetCurrentWindow(ORIGINAL_WINDOW);
941 
942 }
943 
944 /*
945  * CB_CloseWindow - what it says.
946  */
947 
CB_CloseWindow(Widget w,void * data)948 void CB_CloseWindow(Widget w, void *data)
949 {
950   CloseWindow();
951   return;
952 
953 }
954 
955 
956 /*----------------------- Text Viewer/Edit Widget --------------------*/
957 
958 /* The code below is based on xmore.c by Dominic Giampolo */
959 
Editor_Quit(Widget foo,void * arg)960 void Editor_Quit(Widget foo, void *arg)
961 {
962   WinInfo *wi=(WinInfo *)arg;
963 
964   *(wi->num_windows) = *(wi->num_windows) - 1;
965 
966   SetCurrentWindow(XtParent(XtParent(foo)));
967   CloseWindow();
968 
969   /* if (*(wi->num_windows) == 0) exit(0); */
970 
971 }
972 
973 
974 /*
975  * Open a new file in the same window.
976  */
Editor_File(Widget foo,void * arg)977 void Editor_File(Widget foo, void *arg)
978 {
979   WinInfo *wi=(WinInfo *)arg;
980   char *fname;
981 
982   fname = GetFile(wi->cur_path);
983   if (fname)
984    {
985      SetTextWidgetText(wi->text_widget, fname, TRUE);
986      SetLabel(wi->label_widget, fname);
987 
988      if (wi->cur_path)
989        free(wi->cur_path);
990 
991      wi->cur_path = dirname(fname);
992    }
993 }
994 
995 
996 
997 #define MAXLABEL  80
998 
make_text_viewer(char * fname,WinInfo * arg)999 void make_text_viewer(char *fname, WinInfo *arg)
1000 {
1001   Widget w[10];
1002   static char dummy_label[MAXLABEL];
1003   int i, width;
1004   XFont xf;
1005 
1006   for(i=0; i < MAXLABEL-1; i++)
1007     dummy_label[i] = ' ';
1008   dummy_label[i] = '\0';
1009 
1010   w[0] = MakeLabel(dummy_label);
1011 
1012 /*  xf = GetWidgetFont(w[0]);
1013   if (xf != NULL)
1014     width = TextWidth(xf, dummy_label);
1015   else */
1016     width = 600;
1017 
1018   w[1] = MakeTextWidget(fname, TRUE, FALSE, width, 400);
1019   w[2] = MakeButton("Open", Editor_File, arg);
1020   w[3] = MakeButton("Quit", Editor_Quit, arg);
1021 
1022   SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
1023   SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
1024   SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]);
1025 
1026   AttachEdge(w[0], RIGHT_EDGE,  ATTACH_LEFT);
1027   AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP);
1028 
1029   AttachEdge(w[1], LEFT_EDGE,   ATTACH_LEFT);
1030   AttachEdge(w[1], RIGHT_EDGE,  ATTACH_RIGHT);
1031   AttachEdge(w[1], TOP_EDGE,    ATTACH_TOP);
1032   AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM);
1033 
1034   AttachEdge(w[2], LEFT_EDGE,   ATTACH_LEFT);
1035   AttachEdge(w[2], RIGHT_EDGE,  ATTACH_LEFT);
1036   AttachEdge(w[2], TOP_EDGE,    ATTACH_BOTTOM);
1037   AttachEdge(w[2], BOTTOM_EDGE, ATTACH_BOTTOM);
1038 
1039   AttachEdge(w[3], LEFT_EDGE,   ATTACH_LEFT);
1040   AttachEdge(w[3], RIGHT_EDGE,  ATTACH_LEFT);
1041   AttachEdge(w[3], TOP_EDGE,    ATTACH_BOTTOM);
1042   AttachEdge(w[3], BOTTOM_EDGE, ATTACH_BOTTOM);
1043 
1044   arg->text_widget  = w[1];
1045   arg->label_widget = w[0];
1046 
1047   ShowDisplay();
1048 
1049   SetLabel(w[0], fname);   /* set the real filename */
1050 }
1051 
1052 
make_text_editor(char * fname,WinInfo * arg)1053 void make_text_editor(char *fname, WinInfo *arg)
1054 {
1055   Widget w[10];
1056   static char dummy_label[MAXLABEL];
1057   int i, width;
1058   XFont xf;
1059 
1060   for(i=0; i < MAXLABEL-1; i++)
1061     dummy_label[i] = ' ';
1062   dummy_label[i] = '\0';
1063 
1064   w[0] = MakeLabel(dummy_label);
1065 
1066 /*  xf = GetWidgetFont(w[0]);
1067   if (xf != NULL)
1068     width = TextWidth(xf, dummy_label);
1069   else */
1070     width = 600;
1071 
1072   w[1] = MakeTextWidget(fname, TRUE, TRUE, width, 400);
1073   w[2] = MakeButton("Open", Editor_File, arg);
1074   w[3] = MakeButton("Save", NULL, arg);
1075   w[4] = MakeButton("Save as", NULL, arg);
1076   w[5] = MakeButton("Exec", NULL, arg);
1077   w[6] = MakeButton("Run", NULL, arg);
1078   w[7] = MakeButton("GUI", NULL, arg);
1079   w[8] = MakeButton("Quit", Editor_Quit, arg);
1080 
1081   SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
1082   SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
1083   SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]);
1084   SetWidgetPos(w[4], PLACE_UNDER, w[1], PLACE_RIGHT, w[3]);
1085   SetWidgetPos(w[5], PLACE_UNDER, w[1], PLACE_RIGHT, w[4]);
1086   SetWidgetPos(w[6], PLACE_UNDER, w[1], PLACE_RIGHT, w[5]);
1087   SetWidgetPos(w[7], PLACE_UNDER, w[1], PLACE_RIGHT, w[6]);
1088   SetWidgetPos(w[8], PLACE_UNDER, w[1], PLACE_RIGHT, w[7]);
1089 
1090   AttachEdge(w[0], RIGHT_EDGE,  ATTACH_LEFT);
1091   AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP);
1092 
1093   AttachEdge(w[1], LEFT_EDGE,   ATTACH_LEFT);
1094   AttachEdge(w[1], RIGHT_EDGE,  ATTACH_RIGHT);
1095   AttachEdge(w[1], TOP_EDGE,    ATTACH_TOP);
1096   AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM);
1097 
1098   for(i=2;i<=8;i++) {
1099      AttachEdge(w[i], LEFT_EDGE,   ATTACH_LEFT);
1100      AttachEdge(w[i], RIGHT_EDGE,  ATTACH_LEFT);
1101      AttachEdge(w[i], TOP_EDGE,    ATTACH_BOTTOM);
1102      AttachEdge(w[i], BOTTOM_EDGE, ATTACH_BOTTOM);
1103   }
1104 
1105   arg->text_widget  = w[1];
1106   arg->label_widget = w[0];
1107 
1108   ShowDisplay();
1109 
1110   SetLabel(w[0], fname);   /* set the real filename */
1111 }
1112 
1113 
1114 /*
1115  * CB_Browse() - Text viewer callback. Ideal for help files.
1116  *
1117  */
1118 
CB_Browse(Widget w,void * data)1119 void CB_Browse(Widget w, void *data)
1120 {
1121 
1122   char *fname;
1123   int  num_windows=1;
1124   Widget this;
1125   WinInfo *wi;
1126 
1127 
1128   fname = (char *) data;
1129   if ( !strcmp(fname,"NULL") ) fname = GetFile(NULL);
1130   if ( !fname ) return;
1131 
1132   this = MakeWindow("GrADS Text Viewer", SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
1133   if ( w == NULL ) return;
1134 
1135   wi = (WinInfo *)calloc(sizeof(WinInfo), 1);
1136   if (wi == NULL) return;
1137 
1138   wi->num_windows = &num_windows;
1139   wi->cur_path = dirname(fname);
1140 
1141   make_text_viewer(fname, wi);
1142 
1143 }
1144 
CB_Edit(Widget w,void * data)1145 void CB_Edit(Widget w, void *data)
1146 {
1147 
1148   char *fname;
1149   int  num_windows=1;
1150   Widget this;
1151   WinInfo *wi;
1152 
1153   fname = (char *)data;
1154   if ( !strcmp(fname,"NULL") ) fname = GetFile(NULL);
1155   if ( !fname ) return;
1156 
1157   this = MakeWindow("GrADS Text Editor", SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
1158   if ( w == NULL ) return;
1159 
1160   wi = (WinInfo *)calloc(sizeof(WinInfo), 1);
1161   if (wi == NULL) return;
1162 
1163   wi->num_windows = &num_windows;
1164   wi->cur_path = dirname(fname);
1165 
1166   make_text_editor(fname, wi);
1167 
1168 }
1169 
1170 
1171