1 | /***************************************
2 | $Header$
3 |
4 | This is a Glade front end to the little phase field/fluid structure
5 | interactions program based on PETSc, but can serve as a front end to a
6 | variety of PETSc programs with minor adjustments.
7 |
8 | Callback functions are grouped here according to where they appear in the
9 | main window (except on_run_clicked is below main window items), then the run
10 | control dialog, and save dialog.
11 |
12 | I haven't put function comments in to keep the line count down, the functions
13 | are generally pretty simple GTK+ callbacks.
14 | ***************************************/
15 |
16 |
17 | /* Includes, using GTK_ENABLE_BROKEN to enable the GtkText widget for now. */
18 | #include <glade/glade.h>
19 | #include <gnome.h>
20 | #include <libgnomeui/libgnomeui.h>
21 | #include <stdio.h>
22 | #include <math.h>
23 |
24 | GladeXML *xml;
25 | FILE *simulation_input_file, *simulation_output_file;
26 |
27 | /* Simple debugging macro */
28 | #ifdef DEBUG
29 | #define DPRINTF printf
30 | #else
31 | #define DPRINTF(fmt...)
32 | #endif
33 |
34 | /* Discretization stuff */
35 | double Lx;
36 | int nx;
37 |
38 | void on_width_changed (GtkWidget *width, gpointer user_data) {
39 | G_CONST_RETURN gchar *entrytext;
40 | entrytext = gtk_entry_get_text (GTK_ENTRY (width));
41 | sscanf (entrytext, "%lf", &Lx);
42 | DPRINTF ("Width set to %g\n", Lx); }
43 |
44 | void on_resolution_changed (GtkWidget *resolution, gpointer user_data) {
45 | /* Note: gtk_spin_button_get_value_as_int doesn't respond to typed entry */
46 | nx = gtk_spin_button_get_value (GTK_SPIN_BUTTON (resolution));
47 | DPRINTF ("Resolution set to %d\n", nx); }
48 |
49 | /* Timestep stuff */
50 | double dt, dt_factor, dt_max;
51 | int last_tstep;
52 |
53 | void on_timestep_changed (GtkWidget *timestep, gpointer user_data) {
54 | G_CONST_RETURN gchar *entrytext;
55 | entrytext = gtk_entry_get_text (GTK_ENTRY (timestep));
56 | sscanf (entrytext, "%lf", &dt);
57 | DPRINTF ("Timestep set to %g\n", dt); }
58 |
59 | void on_time_factor_changed (GtkWidget *time_factor, gpointer user_data) {
60 | G_CONST_RETURN gchar *entrytext;
61 | entrytext = gtk_entry_get_text (GTK_ENTRY (time_factor));
62 | sscanf (entrytext, "%lf", &dt_factor);
63 | DPRINTF ("Time factor set to %g\n", dt_factor); }
64 |
65 | void on_max_timestep_changed (GtkWidget *max_timestep, gpointer user_data) {
66 | G_CONST_RETURN gchar *entrytext;
67 | entrytext = gtk_entry_get_text (GTK_ENTRY (max_timestep));
68 | sscanf (entrytext, "%lf", &dt_max);
69 | DPRINTF ("Max timestep set to %g\n", dt_max); }
70 |
71 | void on_last_timestep_changed (GtkWidget *last_timestep, gpointer user_data) {
72 | /* Note: gtk_spin_button_get_value_as_int doesn't respond to typed entry */
73 | last_tstep = gtk_spin_button_get_value (GTK_SPIN_BUTTON (last_timestep));
74 | DPRINTF ("Last timestep set to %d\n", last_tstep); }
75 |
76 | /* Display stuff */
77 | gboolean display_x, display_text;
78 |
79 | void on_xdisplay_toggled (GtkWidget *xdisplay, gpointer user_data) {
80 | display_x = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (xdisplay));
81 | DPRINTF (display_x ? "Using X display\n" : "Not using X display\n"); }
82 |
83 | void on_textdisplay_toggled (GtkWidget *textdisplay, gpointer user_data) {
84 | display_text = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(textdisplay));
85 | DPRINTF(display_text ? "Using text display\n" : "Not using text display\n");}
86 |
87 | /* Remote host stuff */
88 | gboolean remote_host;
89 | G_CONST_RETURN gchar *remote_hostname;
90 | gchar thetransport[50];
91 |
92 | void on_remote_check_toggled (GtkWidget *remote_check, gpointer user_data) {
93 | if (remote_host = gtk_toggle_button_get_active
94 | (GTK_TOGGLE_BUTTON (remote_check))) {
95 | gtk_widget_set_sensitive
96 | (glade_xml_get_widget (xml, "transport_label"), TRUE);
97 | gtk_widget_set_sensitive
98 | (glade_xml_get_widget (xml, "transport_options"), TRUE);
99 | gtk_widget_set_sensitive
100 | (glade_xml_get_widget (xml, "remote_host_label"), TRUE);
101 | gtk_widget_set_sensitive
102 | (glade_xml_get_widget (xml, "remote_host"), TRUE); }
103 | else {
104 | gtk_widget_set_sensitive
105 | (glade_xml_get_widget (xml, "transport_label"), FALSE);
106 | gtk_widget_set_sensitive
107 | (glade_xml_get_widget (xml, "transport_options"), FALSE);
108 | gtk_widget_set_sensitive
109 | (glade_xml_get_widget (xml, "remote_host_label"), FALSE);
110 | gtk_widget_set_sensitive
111 | (glade_xml_get_widget (xml, "remote_host"), FALSE); }
112 | DPRINTF (remote_host ? "Using remote host\n" : "Using local host\n"); }
113 |
114 | void on_ssh_item_activate (GtkWidget *widget, gpointer user_data) {
115 | sprintf (thetransport, "ssh");
116 | DPRINTF ("Transport type = %s\n", thetransport); }
117 |
118 | void on_rsh_item_activate (GtkWidget *widget, gpointer user_data) {
119 | sprintf (thetransport, "rsh");
120 | DPRINTF ("Transport type = %s\n", thetransport); }
121 |
122 | void on_remote_host_changed (GtkWidget *remote_host, gpointer user_data) {
123 | remote_hostname = gtk_entry_get_text (GTK_ENTRY (remote_host));
124 | DPRINTF ("Remote host set to %s\n", remote_hostname); }
125 |
126 | /* MPI stuff */
127 | G_CONST_RETURN gchar *mpirun_command;
128 | int number_cpus;
129 |
130 | void on_mpirun_changed (GtkWidget *mpirun, gpointer user_data) {
131 | mpirun_command = gtk_entry_get_text (GTK_ENTRY (mpirun));
132 | DPRINTF ("MPIrun command set to %s\n", mpirun_command); }
133 |
134 | void on_num_cpus_changed (GtkWidget *num_cpus, gpointer user_data) {
135 | /* Note: gtk_spin_button_get_value_as_int doesn't respond to typed entry */
136 | number_cpus = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (num_cpus));
137 | if (number_cpus > 1) {
138 | gtk_widget_set_sensitive
139 | (glade_xml_get_widget (xml, "mpirun_label"), TRUE);
140 | gtk_widget_set_sensitive
141 | (glade_xml_get_widget (xml, "mpirun"), TRUE); }
142 | else {
143 | gtk_widget_set_sensitive
144 | (glade_xml_get_widget (xml, "mpirun_label"), FALSE);
145 | gtk_widget_set_sensitive
146 | (glade_xml_get_widget (xml, "mpirun"), FALSE); }
147 | DPRINTF ("Num_CPUs set to %d\n", number_cpus); }
148 |
149 | /* Dimensionality */
150 | gboolean twodee;
151 |
152 | void on_2d_activate (GtkWidget *unused, gpointer user_data) {
153 | twodee = TRUE; DPRINTF ("Simulating in two dimensions\n"); }
154 |
155 | void on_3d_activate (GtkWidget *unused, gpointer user_data) {
156 | twodee = FALSE; DPRINTF ("Simulating in three dimensions\n"); }
157 |
158 | /* Load and save (unfinished!) */
159 | gchar *options_filename = NULL;
160 | void on_load_ok_clicked (GtkWidget *load_file, gpointer user_data) {
161 | gtk_widget_hide (load_file); }
162 |
163 | void on_save_ok_clicked (GtkWidget *save_file, gpointer user_data) {
164 | gtk_widget_hide (save_file); }
165 |
166 | /* Toggle buttons */
167 | void on_show_options_toggled (GtkWidget *show_options, gpointer user_data) {
168 | GtkWidget *simulation_options =
169 | glade_xml_get_widget (xml,"simulation_options");
170 | GtkWidget *options_notebook = glade_xml_get_widget (xml,"options_notebook");
171 | gboolean show_options_active =
172 | gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_options));
173 | gboolean simulation_options_active =
174 | gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (simulation_options));
175 | DPRINTF ("on_show_options_toggled: show %d, simulation %d\n",
176 | show_options_active, simulation_options_active);
177 |
178 | if (show_options_active != simulation_options_active)
179 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (simulation_options),
180 | show_options_active);
181 | if (show_options_active)
182 | gtk_widget_show (options_notebook);
183 | else {
184 | GtkWidget *main_window = glade_xml_get_widget (xml, "main_window");
185 | gtk_widget_hide (options_notebook);
186 | gtk_window_resize (GTK_WINDOW (main_window), 1, 1); }
187 | }
188 |
189 | void on_show_output_toggled (GtkWidget *show_output, gpointer user_data) {
190 | GtkWidget *simulation_output =
191 | glade_xml_get_widget (xml,"simulation_output");
192 | GtkWidget *output_window = glade_xml_get_widget (xml,"output_window");
193 | gboolean show_output_active =
194 | gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_output));
195 | gboolean simulation_output_active =
196 | gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (simulation_output));
197 | DPRINTF ("on_show_output_toggled: show %d, simulation %d\n",
198 | show_output_active, simulation_output_active);
199 |
200 | if (show_output_active != simulation_output_active)
201 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (simulation_output),
202 | show_output_active);
203 | if (show_output_active)
204 | gtk_widget_show (output_window);
205 | else
206 | gtk_widget_hide (output_window); }
207 |
208 | /* Menu items, mainly calling things above (SO annoying that menu signals don't
209 | have associated objects!) */
210 | void open_params (GtkWidget *null_widget, gpointer user_data) {
211 | GtkWidget *load_file = glade_xml_get_widget (xml,"load_file");
212 | gtk_widget_show (load_file); }
213 |
214 | void save_params_as (GtkWidget *null_widget, gpointer user_data) {
215 | GtkWidget *save_file = glade_xml_get_widget (xml,"save_file");
216 | gtk_widget_show (save_file); }
217 |
218 | void save_params (GtkWidget *null_widget, gpointer user_data) {
219 | if (options_filename == NULL)
220 | save_params_as (null_widget, user_data); }
221 |
222 | void on_show_options_activate (GtkWidget *null_widget, gpointer user_data) {
223 | GtkWidget *simulation_options =
224 | glade_xml_get_widget (xml,"simulation_options");
225 | GtkWidget *show_options = glade_xml_get_widget (xml,"show_options");
226 | gboolean simulation_options_active =
227 | gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (simulation_options));
228 | gboolean show_options_active =
229 | gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_options));
230 | DPRINTF ("on_show_options_activate: show %d, simulation %d\n",
231 | show_options_active, simulation_options_active);
232 |
233 | /* They will be unequal if this one was activated */
234 | if (simulation_options_active != show_options_active)
235 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_options),
236 | simulation_options_active); }
237 |
238 | void on_show_output_activate (GtkWidget *null_widget, gpointer user_data) {
239 | GtkWidget *simulation_output =
240 | glade_xml_get_widget (xml,"simulation_output");
241 | GtkWidget *show_output = glade_xml_get_widget (xml,"show_output");
242 | gboolean simulation_output_active =
243 | gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (simulation_output));
244 | gboolean show_output_active =
245 | gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_output));
246 | DPRINTF ("on_show_output_activate: show %d, simulation %d\n",
247 | show_output_active, simulation_output_active);
248 |
249 | /* They will be unequal if this one was activated */
250 | if (simulation_output_active != show_output_active)
251 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_output),
252 | simulation_output_active); }
253 |
254 | void on_about_activate (GtkWidget *null_widget, gpointer user_data) {
255 | GtkWidget *about_window = glade_xml_get_widget (xml,"about_window");
256 | gtk_widget_show (about_window); }
257 |
258 | /* The run button! */
259 | gint pipe_input_tag; /* Tag number for gdk_input_add/remove */
260 |
261 | /* First an ancillary function to read from the pipe and write to the window */
262 | void read_simulation_data (gpointer user_data, gint source,
263 | GdkInputCondition condition)
264 | {
265 | int i, len;
266 | gfloat residual;
267 | char simulation_input [200];
268 | gchar start[50], current[50], final[50];
269 | static GtkWidget *output_text=NULL,
270 | *timestep_progressbar, *start_timestep, *current_timestep, *final_timestep,
271 | *newton_progressbar, *start_newton, *current_newton, *final_newton,
272 | *gcr_progressbar, *start_gcr, *current_gcr, *final_gcr;
273 | static gfloat orig_gcr=0., orig_newton=0., tol_gcr=5.0E-4, tol_newton=5.0E-4;
274 | static int orig_timestep = 0;
275 | void on_stop_clicked (GtkWidget *, gpointer);
276 |
277 | if (output_text == NULL) {
278 | output_text = glade_xml_get_widget (xml, "output_text");
279 | timestep_progressbar = glade_xml_get_widget (xml, "timestep_progressbar");
280 | start_timestep = glade_xml_get_widget (xml, "start_timestep");
281 | current_timestep = glade_xml_get_widget (xml, "current_timestep");
282 | final_timestep = glade_xml_get_widget (xml, "final_timestep");
283 | newton_progressbar = glade_xml_get_widget (xml, "newton_progressbar");
284 | start_newton = glade_xml_get_widget (xml, "start_newton");
285 | current_newton = glade_xml_get_widget (xml, "current_newton");
286 | final_newton = glade_xml_get_widget (xml, "final_newton");
287 | gcr_progressbar = glade_xml_get_widget (xml, "gcr_progressbar");
288 | start_gcr = glade_xml_get_widget (xml, "start_gcr");
289 | current_gcr = glade_xml_get_widget (xml, "current_gcr");
290 | final_gcr = glade_xml_get_widget (xml, "final_gcr"); }
291 |
292 | /* Read text until end-of-line */
293 | if (fgets (simulation_input, sizeof (simulation_input),
294 | simulation_input_file) != NULL) {
295 |
296 | /* KSP residual */
297 | if (!(strncmp (simulation_input+4, "KSP", 3)) ||
298 | !(strncmp (simulation_input+5, "KSP", 3)) ||
299 | !(strncmp (simulation_input+6, "KSP", 3)) ||
300 | !(strncmp (simulation_input+7, "KSP", 3)) ||
301 | !(strncmp (simulation_input+8, "KSP", 3))) {
302 | /* Get current GCR residual, set orig and final if necessary */
303 | sscanf (simulation_input, "%d KSP Residual norm %f", &i, &residual);
304 | sprintf (current, "%.4e", residual);
305 | gtk_label_set_text (GTK_LABEL (current_gcr), current);
306 | if (i == 0) {
307 | orig_gcr = residual;
308 | tol_gcr = residual * 1.e-5;
309 | sprintf (start, "%.4e", orig_gcr);
310 | gtk_label_set_text (GTK_LABEL (start_gcr), start);
311 | sprintf (final, "%.4e", tol_gcr);
312 | gtk_label_set_text (GTK_LABEL (final_gcr), final); }
313 |
314 | /* Reset when falls below tolerance (it's done), plot progress */
315 | if (residual < tol_gcr)
316 | residual = orig_gcr;
317 | if (residual <= orig_gcr)
318 | gtk_progress_bar_update (GTK_PROGRESS_BAR (gcr_progressbar),
319 | (gfloat) log(orig_gcr/residual) /
320 | log(orig_gcr/tol_gcr)); }
321 |
322 | /* Newton residual */
323 | else if (!(strncmp (simulation_input+4, "SNES", 4)) ||
324 | !(strncmp (simulation_input+5, "SNES", 4)) ||
325 | !(strncmp (simulation_input+6, "SNES", 4))) {
326 | /* Reset GCR orig and progress bar */
327 | orig_gcr = 0.0;
328 | gtk_progress_bar_update (GTK_PROGRESS_BAR (gcr_progressbar),
329 | (gfloat) 0.0);
330 | /* Get current Newton residual, set orig and final if necessary */
331 | sscanf (simulation_input, "%d SNES Function norm %f", &i, &residual);
332 | sprintf (current, "%.4e", residual);
333 | gtk_label_set_text (GTK_LABEL (current_newton), current);
334 | if (i == 0) {
335 | orig_newton = residual;
336 | tol_newton = residual * 1.e-8;
337 | sprintf (start, "%.4e", orig_newton);
338 | gtk_label_set_text (GTK_LABEL (start_newton), start);
339 | sprintf (final, "%.4e", tol_newton);
340 | gtk_label_set_text (GTK_LABEL (final_newton), final); }
341 |
342 | /* Reset when falls below tolerance (it's done), plot progress */
343 | if (residual < tol_newton)
344 | residual = orig_newton;
345 | if (residual <= orig_newton)
346 | gtk_progress_bar_update (GTK_PROGRESS_BAR (newton_progressbar),
347 | (gfloat) log(orig_newton/residual) /
348 | log(orig_newton/tol_newton)); }
349 |
350 | /* Timestep */
351 | else if (!(strncmp (simulation_input, "timestep", 8))) {
352 | sscanf (simulation_input, "timestep %d", &i);
353 | sprintf (current, "%d", i);
354 | gtk_label_set_text (GTK_LABEL (current_timestep), current);
355 | if (i == 0) {
356 | sprintf (current, "%d", last_tstep);
357 | gtk_label_set_text (GTK_LABEL (final_timestep), current); }
358 | gtk_progress_bar_update (GTK_PROGRESS_BAR (timestep_progressbar),
359 | (gfloat) i/last_tstep); }
360 |
361 | /* End of simulation */
362 | else if (!(strncmp (simulation_input, "Game over", 9)))
363 | on_stop_clicked
364 | (glade_xml_get_widget (xml, "output_window"), NULL);
365 |
366 | /* Write the text to the output widget in the run dialog */
367 | else
368 | {
369 | GtkTextBuffer *buffer = gtk_text_view_get_buffer
370 | (GTK_TEXT_VIEW (output_text));
371 | GtkTextIter iter;
372 | gtk_text_buffer_get_end_iter (buffer, &iter);
373 | gtk_text_buffer_insert
374 | (buffer, &iter, simulation_input, strlen (simulation_input));
375 | }
376 | }
377 | }
378 |
379 |
380 | #define MAX_COMMAND_LINE_OPTIONS 22
381 |
382 | int from_simulation_pipe[2], to_simulation_pipe[2];
383 |
384 | void on_run_activate (GtkWidget *null_widget, gpointer user_data) {
385 | gchar command_line [MAX_COMMAND_LINE_OPTIONS][50],
386 | clinestr [MAX_COMMAND_LINE_OPTIONS*50];
387 | int simulation_pid;
388 | int command = 0, i;
389 |
390 | /* Font: -misc-fixed-medium-r-semicondensed-*-*-110-c-*-iso10646-1, or
391 | -misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso10646-1 (or 70) */
392 |
393 | /* Construct the command line string, of special and standard options */
394 | if (remote_host) {
395 | strcpy (command_line[command++], thetransport);
396 | if (!strcmp (thetransport, "ssh"))
397 | sprintf (command_line[command++], "-AX");
398 | strcpy (command_line[command++], remote_hostname); }
399 | if (number_cpus > 1) {
400 | sprintf (command_line[command++], "%s", mpirun_command);
401 | sprintf (command_line[command++], "-np");
402 | sprintf (command_line[command++], "%d", number_cpus); }
403 | /* Note that if we add to this list, we must also modify the COMMAND_LINE
404 | macros above, and also the execlp command below. */
405 | sprintf (command_line[command], CHTS_PATH);
406 | strcat (command_line[command++], "/chts");
407 | sprintf (command_line[command++], "-ts_max_steps");
408 | sprintf (command_line[command++], "%d", last_tstep);
409 | sprintf (command_line[command++], "-mx");
410 | sprintf (command_line[command++], "%d", nx);
411 | sprintf (command_line[command++], "-my");
412 | sprintf (command_line[command++], "%d", nx);
413 | sprintf (command_line[command++], "-mz");
414 | sprintf (command_line[command++], "%d", nx);
415 | sprintf (command_line[command++], "-dt");
416 | sprintf (command_line[command++], "%e", dt);
417 | if (!display_x)
418 | sprintf (command_line[command++], "-no_contours");
419 | if (twodee)
420 | sprintf (command_line[command++], "-twodee");
421 | sprintf (command_line[command++], "-ts_monitor");
422 | sprintf (command_line[command++], "-snes_monitor");
423 | sprintf (command_line[command++], "-ksp_monitor");
424 |
425 | while (command < MAX_COMMAND_LINE_OPTIONS)
426 | command_line [command++][0] = '\0';
427 | sprintf (clinestr, "Command line:");
428 | for (command = 0;
429 | command < MAX_COMMAND_LINE_OPTIONS && command_line [command][0];
430 | command++)
431 | sprintf (clinestr+strlen(clinestr), " %s", command_line [command]);
432 | sprintf (clinestr+strlen(clinestr), "\n");
433 | DPRINTF ("%s", clinestr);
434 | {
435 | GtkTextBuffer *buffer = gtk_text_view_get_buffer
436 | (GTK_TEXT_VIEW (glade_xml_get_widget (xml, "output_text")));
437 | GtkTextIter iter;
438 | gtk_text_buffer_get_end_iter (buffer, &iter);
439 | gtk_text_buffer_insert
440 | (buffer, &iter, clinestr, strlen (clinestr));
441 | }
442 |
443 | /* Try to spawn a new simulation process. Most of this was shamelessly
444 | ripped from Ken Brakke's Surface Evolver. */
445 | pipe (from_simulation_pipe); /* from simulation stdout */
446 | pipe (to_simulation_pipe); /* to simulation stdin */
447 | simulation_pid = fork ();
448 |
449 | if(simulation_pid==0) { /* child */
450 | close (0);
451 | dup (to_simulation_pipe[0]);
452 | close (to_simulation_pipe[0]);
453 | close (to_simulation_pipe[1]);
454 | close (1);
455 | dup (from_simulation_pipe[1]);
456 | close (from_simulation_pipe[0]);
457 | close (from_simulation_pipe[1]);
458 |
459 | /* Change to the correct directory */
460 | /* if (chdir ("/home/hazelsct/davidch/oscsolid")) {
461 | perror (command_line[0]); exit (1); } */
462 |
463 | /* signal(SIGINT,SIG_IGN); */
464 | /* Okay, so this is a retarded way to do it... :-) */
465 | execlp(command_line[0], command_line[0], command_line[1], command_line[2],
466 | command_line[3], command_line[4], command_line[5], command_line[6],
467 | command_line[7], command_line[8], command_line[9], command_line[10],
468 | command_line[11],command_line[12],command_line[13],command_line[14],
469 | command_line[15],command_line[16],command_line[17],command_line[18],
470 | command_line[19],command_line[20],command_line[21],NULL);
471 | perror (command_line[0]); /* only error gets here */
472 | exit (1);
473 | }
474 |
475 | /* Chui program execution resumes here */
476 | close (from_simulation_pipe[1]);
477 | close (to_simulation_pipe[0]);
478 |
479 | /* simulation_input_file is hooked to stdout of simulation */
480 | simulation_input_file = fdopen (from_simulation_pipe[0], "r");
481 | /* simulation_output_file is hooked to stdin of simulation */
482 | simulation_output_file = fdopen (to_simulation_pipe[1], "w");
483 |
484 | /* Sensitize and desensitize various widgets */
485 | gtk_widget_set_sensitive
486 | (glade_xml_get_widget (xml, "model_options_vbox"), FALSE);
487 | gtk_widget_set_sensitive
488 | (glade_xml_get_widget (xml, "petsc_options_scrolledwindow"), FALSE);
489 | gtk_widget_set_sensitive
490 | (glade_xml_get_widget (xml, "misc_options_vbox"), FALSE);
491 | gtk_widget_set_sensitive
492 | (glade_xml_get_widget (xml, "open"), FALSE);
493 | gtk_widget_set_sensitive
494 | (glade_xml_get_widget (xml, "save"), FALSE);
495 | gtk_widget_set_sensitive
496 | (glade_xml_get_widget (xml, "save_as"), FALSE);
497 | gtk_widget_set_sensitive
498 | (glade_xml_get_widget (xml, "run"), FALSE);
499 | gtk_widget_set_sensitive
500 | (glade_xml_get_widget (xml, "open_button"), FALSE);
501 | gtk_widget_set_sensitive
502 | (glade_xml_get_widget (xml, "save_button"), FALSE);
503 | gtk_widget_set_sensitive
504 | (glade_xml_get_widget (xml, "save_as_button"), FALSE);
505 | gtk_widget_set_sensitive
506 | (glade_xml_get_widget (xml, "run_button"), FALSE);
507 | /* gtk_widget_set_sensitive
508 | (glade_xml_get_widget (xml, "pause"), TRUE);
509 | gtk_widget_set_sensitive
510 | (glade_xml_get_widget (xml, "stop"), TRUE); */
511 |
512 | /* Show the run control table and text output window */
513 | /* gtk_widget_show (output_window); */
514 | if (!(gtk_toggle_button_get_active
515 | (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "show_output"))))) {
516 | gtk_toggle_button_set_active
517 | (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "show_output")), TRUE);
518 | gtk_widget_show (glade_xml_get_widget (xml, "output_window")); }
519 |
520 | /* Add the input function, this will have gtk_main() call
521 | read_simulation_data() when input is received on the pipe. */
522 | pipe_input_tag = gdk_input_add (from_simulation_pipe [0], GDK_INPUT_READ,
523 | read_simulation_data, NULL);
524 | }
525 |
526 | void on_stop_clicked (GtkWidget *output_window, gpointer user_data) {
527 | /* This should really send some kind of "stop" signal to chts and wait for a
528 | reply... interactive options setting, etc. */
529 |
530 | /* Remove the pipe sensitivity and close the files and pipes */
531 | gdk_input_remove (pipe_input_tag);
532 | fclose (simulation_input_file);
533 | fclose (simulation_output_file);
534 | close (from_simulation_pipe [0]);
535 | close (to_simulation_pipe [1]);
536 |
537 | /* Make appropriate widget readjustments */
538 | /* gtk_widget_hide (output_window); */
539 | gtk_widget_set_sensitive
540 | (glade_xml_get_widget (xml, "model_options_vbox"), TRUE);
541 | gtk_widget_set_sensitive
542 | (glade_xml_get_widget (xml, "petsc_options_scrolledwindow"), TRUE);
543 | gtk_widget_set_sensitive
544 | (glade_xml_get_widget (xml, "misc_options_vbox"), TRUE);
545 | gtk_widget_set_sensitive
546 | (glade_xml_get_widget (xml, "open"), TRUE);
547 | gtk_widget_set_sensitive
548 | (glade_xml_get_widget (xml, "save"), TRUE);
549 | gtk_widget_set_sensitive
550 | (glade_xml_get_widget (xml, "save_as"), TRUE);
551 | gtk_widget_set_sensitive
552 | (glade_xml_get_widget (xml, "run"), TRUE);
553 | gtk_widget_set_sensitive
554 | (glade_xml_get_widget (xml, "open_button"), TRUE);
555 | gtk_widget_set_sensitive
556 | (glade_xml_get_widget (xml, "save_button"), TRUE);
557 | gtk_widget_set_sensitive
558 | (glade_xml_get_widget (xml, "save_as_button"), TRUE);
559 | gtk_widget_set_sensitive
560 | (glade_xml_get_widget (xml, "run_button"), TRUE);
561 | /* gtk_widget_set_sensitive
562 | (glade_xml_get_widget (xml, "pause"), FALSE);
563 | gtk_widget_set_sensitive
564 | (glade_xml_get_widget (xml, "stop"), FALSE); */}
565 |
566 | /* Does nothing for now */
567 | void on_pause_clicked (GtkWidget *forgot, gpointer user_data) {
568 | DPRINTF ("Pause was clicked\n");
569 | return; }
570 |
571 | /* And finally, main() */
572 | int main (int argc, char *argv[])
573 | {
574 | gchar buff[200];
575 | GtkWidget *transport_options, *transport_menu, *ssh_item, *rsh_item,
576 | *dimension_options, *dimension_menu;
577 |
578 | /* Basic init stufff */
579 | gnome_program_init ("CHUI", VERSION, LIBGNOMEUI_MODULE, argc, argv, NULL);
580 |
581 | /* Load the interface, display the initial window, and connect the signals */
582 | strncpy (buff, GLADE_DIRECTORY, 187);
583 | strcat (buff, "/chui.glade");
584 | xml = glade_xml_new (buff, NULL, NULL);
585 | glade_xml_signal_autoconnect (xml);
586 |
587 | /* For some reason, option menus don't quite work in Glade, so I had to make
588 | a popup menu and attach it to the option menu */
589 | /* transport_options = glade_xml_get_widget (xml, "transport_options");
590 | gtk_option_menu_remove_menu (GTK_OPTION_MENU (transport_options));
591 | transport_menu = glade_xml_get_widget (xml, "transport_menu");
592 | gtk_option_menu_set_menu (GTK_OPTION_MENU(transport_options),transport_menu);
593 | gtk_widget_show (transport_menu);
594 | dimension_options = glade_xml_get_widget (xml, "dimension_options");
595 | gtk_option_menu_remove_menu (GTK_OPTION_MENU (dimension_options));
596 | dimension_menu = glade_xml_get_widget (xml, "dimension_menu");
597 | gtk_option_menu_set_menu (GTK_OPTION_MENU(dimension_options),dimension_menu);
598 | gtk_widget_show (dimension_menu); */
599 |
600 | /* Call handlers to set initial values from Glade defaults */
601 | on_width_changed (glade_xml_get_widget (xml, "width"), NULL);
602 | on_resolution_changed (glade_xml_get_widget (xml, "resolution"), NULL);
603 | on_timestep_changed (glade_xml_get_widget (xml, "timestep"), NULL);
604 | on_time_factor_changed (glade_xml_get_widget (xml, "time_factor"), NULL);
605 | on_max_timestep_changed (glade_xml_get_widget (xml, "max_timestep"), NULL);
606 | on_last_timestep_changed (glade_xml_get_widget (xml, "last_timestep"), NULL);
607 | on_xdisplay_toggled (glade_xml_get_widget (xml, "xdisplay"), NULL);
608 | on_textdisplay_toggled (glade_xml_get_widget (xml, "textdisplay"), NULL);
609 | on_remote_check_toggled (glade_xml_get_widget (xml, "remote_check"), NULL);
610 | on_ssh_item_activate (NULL, NULL);
611 | on_remote_host_changed (glade_xml_get_widget (xml, "remote_host"), NULL);
612 | on_mpirun_changed (glade_xml_get_widget (xml, "mpirun"), NULL);
613 | on_num_cpus_changed (glade_xml_get_widget (xml, "num_cpus"), NULL);
614 | on_3d_activate (NULL, NULL);
615 |
616 | /* Off we go! */
617 | gtk_main();
618 |
619 | return 0;
620 | }