1 | /*************************************** 2 | $Header: /cvsroot/petscgraphics/chui.c,v 1.13 2004/05/25 13:27:27 hazelsct Exp $ 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 | }