1 | /*************************************** 2 | $Header: /cvsroot/petscgraphics/chui.c,v 1.9 2003/08/04 14:14:47 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 | /* */ 18 | 19 | #include <gtk/gtk.h> 20 | #include <glade/glade.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 | 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_as_int (GTK_SPIN_BUTTON (resolution)); */ 47 | gchar *entrytext; 48 | entrytext = gtk_entry_get_text (GTK_ENTRY (resolution)); 49 | sscanf (entrytext, "%d", &nx); 50 | DPRINTF ("Resolution set to %d\n", nx); } 51 | 52 | /* Timestep stuff */ 53 | double dt, dt_factor, dt_max; 54 | int last_tstep; 55 | 56 | void on_timestep_changed (GtkWidget *timestep, gpointer user_data) { 57 | gchar *entrytext; 58 | entrytext = gtk_entry_get_text (GTK_ENTRY (timestep)); 59 | sscanf (entrytext, "%lf", &dt); 60 | DPRINTF ("Timestep set to %g\n", dt); } 61 | 62 | void on_time_factor_changed (GtkWidget *time_factor, gpointer user_data) { 63 | gchar *entrytext; 64 | entrytext = gtk_entry_get_text (GTK_ENTRY (time_factor)); 65 | sscanf (entrytext, "%lf", &dt_factor); 66 | DPRINTF ("Time factor set to %g\n", dt_factor); } 67 | 68 | void on_max_timestep_changed (GtkWidget *max_timestep, gpointer user_data) { 69 | gchar *entrytext; 70 | entrytext = gtk_entry_get_text (GTK_ENTRY (max_timestep)); 71 | sscanf (entrytext, "%lf", &dt_max); 72 | DPRINTF ("Max timestep set to %g\n", dt_max); } 73 | 74 | void on_last_timestep_changed (GtkWidget *last_timestep, gpointer user_data) { 75 | gchar *entrytext; 76 | entrytext = gtk_entry_get_text (GTK_ENTRY (last_timestep)); 77 | sscanf (entrytext, "%d", &last_tstep); 78 | DPRINTF ("Last timestep set to %d\n", last_tstep); } 79 | 80 | /* Display stuff */ 81 | gboolean display_x, display_text; 82 | 83 | void on_xdisplay_toggled (GtkWidget *xdisplay, gpointer user_data) { 84 | display_x = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (xdisplay)); 85 | DPRINTF (display_x ? "Using X display\n" : "Not using X display\n"); } 86 | 87 | void on_textdisplay_toggled (GtkWidget *textdisplay, gpointer user_data) { 88 | display_text = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(textdisplay)); 89 | DPRINTF(display_text ? "Using text display\n" : "Not using text display\n");} 90 | 91 | /* Remote host stuff */ 92 | gboolean remote_host; 93 | gchar *remote_hostname, thetransport[50]; 94 | 95 | void on_remote_check_toggled (GtkWidget *remote_check, gpointer user_data) { 96 | if (remote_host = gtk_toggle_button_get_active 97 | (GTK_TOGGLE_BUTTON (remote_check))) { 98 | gtk_widget_set_sensitive 99 | (glade_xml_get_widget (xml, "transport_label"), TRUE); 100 | gtk_widget_set_sensitive 101 | (glade_xml_get_widget (xml, "transport_options"), TRUE); 102 | gtk_widget_set_sensitive 103 | (glade_xml_get_widget (xml, "remote_host_label"), TRUE); 104 | gtk_widget_set_sensitive 105 | (glade_xml_get_widget (xml, "remote_host"), TRUE); } 106 | else { 107 | gtk_widget_set_sensitive 108 | (glade_xml_get_widget (xml, "transport_label"), FALSE); 109 | gtk_widget_set_sensitive 110 | (glade_xml_get_widget (xml, "transport_options"), FALSE); 111 | gtk_widget_set_sensitive 112 | (glade_xml_get_widget (xml, "remote_host_label"), FALSE); 113 | gtk_widget_set_sensitive 114 | (glade_xml_get_widget (xml, "remote_host"), FALSE); } 115 | DPRINTF (remote_host ? "Using remote host\n" : "Using local host\n"); } 116 | 117 | void on_ssh_item_activate (GtkWidget *widget, gpointer user_data) { 118 | sprintf (thetransport, "ssh"); 119 | DPRINTF ("Transport type = %s\n", thetransport); } 120 | 121 | void on_rsh_item_activate (GtkWidget *widget, gpointer user_data) { 122 | sprintf (thetransport, "rsh"); 123 | DPRINTF ("Transport type = %s\n", thetransport); } 124 | 125 | void on_remote_host_changed (GtkWidget *remote_host, gpointer user_data) { 126 | remote_hostname = gtk_entry_get_text (GTK_ENTRY (remote_host)); 127 | DPRINTF ("Remote host set to %s\n", remote_hostname); } 128 | 129 | /* MPI stuff */ 130 | gchar *mpirun_command; 131 | int number_cpus; 132 | 133 | void on_mpirun_changed (GtkWidget *mpirun, gpointer user_data) { 134 | mpirun_command = gtk_entry_get_text (GTK_ENTRY (mpirun)); 135 | DPRINTF ("MPIrun command set to %s\n", mpirun_command); } 136 | 137 | void on_num_cpus_changed (GtkWidget *num_cpus, gpointer user_data) { 138 | /* Note: gtk_spin_button_get_value_as_int doesn't respond to typed entry */ 139 | /* nx = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (num_cpus)); */ 140 | gchar *entrytext; 141 | entrytext = gtk_entry_get_text (GTK_ENTRY (num_cpus)); 142 | sscanf (entrytext, "%d", &number_cpus); 143 | if (number_cpus > 1) { 144 | gtk_widget_set_sensitive 145 | (glade_xml_get_widget (xml, "mpirun_label"), TRUE); 146 | gtk_widget_set_sensitive 147 | (glade_xml_get_widget (xml, "mpirun"), TRUE); } 148 | else { 149 | gtk_widget_set_sensitive 150 | (glade_xml_get_widget (xml, "mpirun_label"), FALSE); 151 | gtk_widget_set_sensitive 152 | (glade_xml_get_widget (xml, "mpirun"), FALSE); } 153 | DPRINTF ("Num_CPUs set to %d\n", number_cpus); } 154 | 155 | /* Dimensionality */ 156 | gboolean twodee; 157 | 158 | void on_2d_activate (GtkWidget *unused, gpointer user_data) { 159 | twodee = TRUE; DPRINTF ("Simulating in two dimensions\n"); } 160 | 161 | void on_3d_activate (GtkWidget *unused, gpointer user_data) { 162 | twodee = FALSE; DPRINTF ("Simulating in three dimensions\n"); } 163 | 164 | /* Load and save (unfinished!) */ 165 | void on_load_ok_clicked (GtkWidget *load_file, gpointer user_data) { 166 | gtk_widget_hide (load_file); } 167 | 168 | void on_save_ok_clicked (GtkWidget *save_file, gpointer user_data) { 169 | gtk_widget_hide (save_file); } 170 | 171 | /* Toggle buttons */ 172 | void on_show_options_toggled (GtkWidget *options_notebook, gpointer user_data){ 173 | if (gtk_toggle_button_get_active 174 | (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "show_options")))) 175 | gtk_widget_show (options_notebook); 176 | else 177 | gtk_widget_hide (options_notebook); } 178 | 179 | void on_show_output_toggled (GtkWidget *output_window, gpointer user_data) { 180 | if (gtk_toggle_button_get_active 181 | (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "show_output")))) 182 | gtk_widget_show (output_window); 183 | else 184 | gtk_widget_hide (output_window); } 185 | 186 | /* The run button! */ 187 | gint pipe_input_tag; /* Tag number for gdk_input_add/remove */ 188 | 189 | /* First an ancillary function to read from the pipe and write to the window */ 190 | void read_simulation_data (gpointer user_data, gint source, 191 | GdkInputCondition condition) 192 | { 193 | int i, len; 194 | gfloat residual; 195 | char simulation_input [200]; 196 | gchar start[50], current[50], final[50]; 197 | static GtkWidget *output_text=NULL, 198 | *timestep_progressbar, *start_timestep, *current_timestep, *final_timestep, 199 | *newton_progressbar, *start_newton, *current_newton, *final_newton, 200 | *gcr_progressbar, *start_gcr, *current_gcr, *final_gcr; 201 | static gfloat orig_gcr=0., orig_newton=0., tol_gcr=5.0E-4, tol_newton=5.0E-4; 202 | static int orig_timestep = 0; 203 | void on_stop_clicked (GtkWidget *, gpointer); 204 | 205 | if (output_text == NULL) { 206 | output_text = glade_xml_get_widget (xml, "output_text"); 207 | timestep_progressbar = glade_xml_get_widget (xml, "timestep_progressbar"); 208 | start_timestep = glade_xml_get_widget (xml, "start_timestep"); 209 | current_timestep = glade_xml_get_widget (xml, "current_timestep"); 210 | final_timestep = glade_xml_get_widget (xml, "final_timestep"); 211 | newton_progressbar = glade_xml_get_widget (xml, "newton_progressbar"); 212 | start_newton = glade_xml_get_widget (xml, "start_newton"); 213 | current_newton = glade_xml_get_widget (xml, "current_newton"); 214 | final_newton = glade_xml_get_widget (xml, "final_newton"); 215 | gcr_progressbar = glade_xml_get_widget (xml, "gcr_progressbar"); 216 | start_gcr = glade_xml_get_widget (xml, "start_gcr"); 217 | current_gcr = glade_xml_get_widget (xml, "current_gcr"); 218 | final_gcr = glade_xml_get_widget (xml, "final_gcr"); } 219 | 220 | /* Read text until end-of-line */ 221 | if (fgets (simulation_input, sizeof (simulation_input), 222 | simulation_input_file) != NULL) { 223 | 224 | /* KSP residual */ 225 | if (!(strncmp (simulation_input+4, "KSP", 3)) || 226 | !(strncmp (simulation_input+5, "KSP", 3)) || 227 | !(strncmp (simulation_input+6, "KSP", 3)) || 228 | !(strncmp (simulation_input+7, "KSP", 3)) || 229 | !(strncmp (simulation_input+8, "KSP", 3))) { 230 | /* Get current GCR residual, set orig and final if necessary */ 231 | sscanf (simulation_input, "%d KSP Residual norm %f", &i, &residual); 232 | sprintf (current, "%.4e", residual); 233 | gtk_label_set_text (GTK_LABEL (current_gcr), current); 234 | if (i == 0) { 235 | orig_gcr = residual; 236 | tol_gcr = residual * 1.e-5; 237 | sprintf (start, "%.4e", orig_gcr); 238 | gtk_label_set_text (GTK_LABEL (start_gcr), start); 239 | sprintf (final, "%.4e", tol_gcr); 240 | gtk_label_set_text (GTK_LABEL (final_gcr), final); } 241 | 242 | /* Reset when falls below tolerance (it's done), plot progress */ 243 | if (residual < tol_gcr) 244 | residual = orig_gcr; 245 | if (residual <= orig_gcr) 246 | gtk_progress_bar_update (GTK_PROGRESS_BAR (gcr_progressbar), 247 | (gfloat) log(orig_gcr/residual) / 248 | log(orig_gcr/tol_gcr)); } 249 | 250 | /* Newton residual */ 251 | else if (!(strncmp (simulation_input+4, "SNES", 4)) || 252 | !(strncmp (simulation_input+5, "SNES", 4)) || 253 | !(strncmp (simulation_input+6, "SNES", 4))) { 254 | /* Reset GCR orig and progress bar */ 255 | orig_gcr = 0.0; 256 | gtk_progress_bar_update (GTK_PROGRESS_BAR (gcr_progressbar), 257 | (gfloat) 0.0); 258 | /* Get current Newton residual, set orig and final if necessary */ 259 | sscanf (simulation_input, "%d SNES Function norm %f", &i, &residual); 260 | sprintf (current, "%.4e", residual); 261 | gtk_label_set_text (GTK_LABEL (current_newton), current); 262 | if (i == 0) { 263 | orig_newton = residual; 264 | tol_newton = residual * 1.e-8; 265 | sprintf (start, "%.4e", orig_newton); 266 | gtk_label_set_text (GTK_LABEL (start_newton), start); 267 | sprintf (final, "%.4e", tol_newton); 268 | gtk_label_set_text (GTK_LABEL (final_newton), final); } 269 | 270 | /* Reset when falls below tolerance (it's done), plot progress */ 271 | if (residual < tol_newton) 272 | residual = orig_newton; 273 | if (residual <= orig_newton) 274 | gtk_progress_bar_update (GTK_PROGRESS_BAR (newton_progressbar), 275 | (gfloat) log(orig_newton/residual) / 276 | log(orig_newton/tol_newton)); } 277 | 278 | /* Timestep */ 279 | else if (!(strncmp (simulation_input, "timestep", 8))) { 280 | sscanf (simulation_input, "timestep %d", &i); 281 | sprintf (current, "%d", i); 282 | gtk_label_set_text (GTK_LABEL (current_timestep), current); 283 | if (i == 0) { 284 | sprintf (current, "%d", last_tstep); 285 | gtk_label_set_text (GTK_LABEL (final_timestep), current); } 286 | gtk_progress_bar_update (GTK_PROGRESS_BAR (timestep_progressbar), 287 | (gfloat) i/last_tstep); } 288 | 289 | /* End of simulation */ 290 | else if (!(strncmp (simulation_input, "Game over", 9))) 291 | on_stop_clicked 292 | (glade_xml_get_widget (xml, "run_control_frame"), NULL); 293 | 294 | /* Write the text to the output widget in the run dialog */ 295 | else 296 | gtk_text_insert (GTK_TEXT (output_text), NULL, NULL, NULL, 297 | simulation_input, strlen (simulation_input)); } 298 | } 299 | 300 | 301 | #define MAX_COMMAND_LINE_OPTIONS 22 302 | 303 | int from_simulation_pipe[2], to_simulation_pipe[2]; 304 | 305 | void on_run_clicked (GtkWidget *run_control_frame, gpointer user_data) { 306 | gchar command_line [MAX_COMMAND_LINE_OPTIONS][50], 307 | clinestr [MAX_COMMAND_LINE_OPTIONS*50]; 308 | int simulation_pid; 309 | int command = 0, i; 310 | 311 | /* Font: -misc-fixed-medium-r-semicondensed-*-*-110-c-*-iso10646-1, or 312 | -misc-fixed-medium-r-normal-*-*-80-*-*-c-*-iso10646-1 (or 70) */ 313 | 314 | /* Construct the command line string, of special and standard options */ 315 | if (remote_host) { 316 | strcpy (command_line[command++], thetransport); 317 | if (!strcmp (thetransport, "ssh")) 318 | sprintf (command_line[command++], "-AX"); 319 | strcpy (command_line[command++], remote_hostname); } 320 | if (number_cpus > 1) { 321 | sprintf (command_line[command++], "%s", mpirun_command); 322 | sprintf (command_line[command++], "-np"); 323 | sprintf (command_line[command++], "%d", number_cpus); } 324 | /* Note that if we add to this list, we must also modify the COMMAND_LINE 325 | macros above, and also the execlp command below. */ 326 | sprintf (command_line[command], CHTS_PATH); 327 | strcat (command_line[command++], "/chts"); 328 | sprintf (command_line[command++], "-ts_max_steps"); 329 | sprintf (command_line[command++], "%d", last_tstep); 330 | sprintf (command_line[command++], "-mx"); 331 | sprintf (command_line[command++], "%d", nx); 332 | sprintf (command_line[command++], "-my"); 333 | sprintf (command_line[command++], "%d", nx); 334 | sprintf (command_line[command++], "-mz"); 335 | sprintf (command_line[command++], "%d", nx); 336 | sprintf (command_line[command++], "-dt"); 337 | sprintf (command_line[command++], "%e", dt); 338 | if (!display_x) 339 | sprintf (command_line[command++], "-no_contours"); 340 | if (twodee) 341 | sprintf (command_line[command++], "-twodee"); 342 | sprintf (command_line[command++], "-ts_monitor"); 343 | sprintf (command_line[command++], "-snes_monitor"); 344 | sprintf (command_line[command++], "-ksp_monitor"); 345 | 346 | while (command < MAX_COMMAND_LINE_OPTIONS) 347 | command_line [command++][0] = '\0'; 348 | sprintf (clinestr, "Command line:"); 349 | for (command = 0; 350 | command < MAX_COMMAND_LINE_OPTIONS && command_line [command][0]; 351 | command++) 352 | sprintf (clinestr+strlen(clinestr), " %s", command_line [command]); 353 | sprintf (clinestr+strlen(clinestr), "\n"); 354 | DPRINTF ("%s", clinestr); 355 | gtk_text_insert (GTK_TEXT (glade_xml_get_widget (xml, "output_text")), NULL, 356 | NULL, NULL, clinestr, strlen (clinestr)); 357 | 358 | /* Try to spawn a new simulation process. Most of this was shamelessly 359 | ripped from Ken Brakke's Surface Evolver. */ 360 | pipe (from_simulation_pipe); /* from simulation stdout */ 361 | pipe (to_simulation_pipe); /* to simulation stdin */ 362 | simulation_pid = fork (); 363 | 364 | if(simulation_pid==0) { /* child */ 365 | close (0); 366 | dup (to_simulation_pipe[0]); 367 | close (to_simulation_pipe[0]); 368 | close (to_simulation_pipe[1]); 369 | close (1); 370 | dup (from_simulation_pipe[1]); 371 | close (from_simulation_pipe[0]); 372 | close (from_simulation_pipe[1]); 373 | 374 | /* Change to the correct directory */ 375 | /* if (chdir ("/home/hazelsct/davidch/oscsolid")) { 376 | perror (command_line[0]); exit (1); } */ 377 | 378 | /* signal(SIGINT,SIG_IGN); */ 379 | /* Okay, so this is a retarded way to do it... :-) */ 380 | execlp(command_line[0], command_line[0], command_line[1], command_line[2], 381 | command_line[3], command_line[4], command_line[5], command_line[6], 382 | command_line[7], command_line[8], command_line[9], command_line[10], 383 | command_line[11],command_line[12],command_line[13],command_line[14], 384 | command_line[15],command_line[16],command_line[17],command_line[18], 385 | command_line[19],command_line[20],command_line[21],NULL); 386 | perror (command_line[0]); /* only error gets here */ 387 | exit (1); 388 | } 389 | 390 | /* Chui program execution resumes here */ 391 | close (from_simulation_pipe[1]); 392 | close (to_simulation_pipe[0]); 393 | 394 | /* simulation_input_file is hooked to stdout of simulation */ 395 | simulation_input_file = fdopen (from_simulation_pipe[0], "r"); 396 | /* simulation_output_file is hooked to stdin of simulation */ 397 | simulation_output_file = fdopen (to_simulation_pipe[1], "w"); 398 | 399 | /* Sensitize and desensitize various widgets */ 400 | gtk_widget_set_sensitive 401 | (glade_xml_get_widget (xml, "options_notebook"), FALSE); 402 | gtk_widget_set_sensitive 403 | (glade_xml_get_widget (xml, "load"), FALSE); 404 | gtk_widget_set_sensitive 405 | (glade_xml_get_widget (xml, "save"), FALSE); 406 | gtk_widget_set_sensitive 407 | (glade_xml_get_widget (xml, "run"), FALSE); 408 | gtk_widget_set_sensitive 409 | (glade_xml_get_widget (xml, "pause"), TRUE); 410 | gtk_widget_set_sensitive 411 | (glade_xml_get_widget (xml, "stop"), TRUE); 412 | 413 | /* Show the run control table and text output window */ 414 | /* gtk_widget_show (run_control_frame); */ 415 | if (!(gtk_toggle_button_get_active 416 | (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "show_output"))))) { 417 | gtk_toggle_button_set_active 418 | (GTK_TOGGLE_BUTTON (glade_xml_get_widget (xml, "show_output")), TRUE); 419 | gtk_widget_show (glade_xml_get_widget (xml, "output_window")); } 420 | 421 | /* Add the input function, this will have gtk_main() call 422 | read_simulation_data() when input is received on the pipe. */ 423 | pipe_input_tag = gdk_input_add (from_simulation_pipe [0], GDK_INPUT_READ, 424 | read_simulation_data, NULL); 425 | } 426 | 427 | void on_stop_clicked (GtkWidget *run_control_frame, gpointer user_data) { 428 | /* This should really send some kind of "stop" signal to chts and wait for a 429 | reply... interactive options setting, etc. */ 430 | 431 | /* Remove the pipe sensitivity and close the files and pipes */ 432 | gdk_input_remove (pipe_input_tag); 433 | fclose (simulation_input_file); 434 | fclose (simulation_output_file); 435 | close (from_simulation_pipe [0]); 436 | close (to_simulation_pipe [1]); 437 | 438 | /* Make appropriate widget readjustments */ 439 | /* gtk_widget_hide (run_control_frame); */ 440 | gtk_widget_set_sensitive 441 | (glade_xml_get_widget (xml, "options_notebook"), TRUE); 442 | gtk_widget_set_sensitive 443 | (glade_xml_get_widget (xml, "load"), TRUE); 444 | gtk_widget_set_sensitive 445 | (glade_xml_get_widget (xml, "save"), TRUE); 446 | gtk_widget_set_sensitive 447 | (glade_xml_get_widget (xml, "run"), TRUE); 448 | gtk_widget_set_sensitive 449 | (glade_xml_get_widget (xml, "pause"), FALSE); 450 | gtk_widget_set_sensitive 451 | (glade_xml_get_widget (xml, "stop"), FALSE); } 452 | 453 | /* Does nothing for now */ 454 | void on_pause_clicked (GtkWidget *forgot, gpointer user_data) { 455 | return; } 456 | 457 | /* And finally, main() */ 458 | int main (int argc, char *argv[]) 459 | { 460 | gchar buff[200]; 461 | GtkWidget *transport_options, *transport_menu, *ssh_item, *rsh_item, 462 | *dimension_options, *dimension_menu; 463 | 464 | /* Basic init stufff */ 465 | gtk_init(&argc, &argv); 466 | glade_init(); 467 | 468 | /* Load the interface, display the initial window, and connect the signals */ 469 | strncpy (buff, GLADE_DIRECTORY, 187); 470 | strcat (buff, "/chui.glade"); 471 | xml = glade_xml_new (buff, NULL); 472 | glade_xml_signal_autoconnect (xml); 473 | 474 | /* For some reason, option menus don't quite work in Glade, so I had to make 475 | a popup menu and attach it to the option menu */ 476 | transport_options = glade_xml_get_widget (xml, "transport_options"); 477 | gtk_option_menu_remove_menu (GTK_OPTION_MENU (transport_options)); 478 | transport_menu = glade_xml_get_widget (xml, "transport_menu"); 479 | gtk_option_menu_set_menu (GTK_OPTION_MENU(transport_options),transport_menu); 480 | gtk_widget_show (transport_menu); 481 | dimension_options = glade_xml_get_widget (xml, "dimension_options"); 482 | gtk_option_menu_remove_menu (GTK_OPTION_MENU (dimension_options)); 483 | dimension_menu = glade_xml_get_widget (xml, "dimension_menu"); 484 | gtk_option_menu_set_menu (GTK_OPTION_MENU(dimension_options),dimension_menu); 485 | gtk_widget_show (dimension_menu); 486 | 487 | /* Call handlers to set initial values from Glade defaults */ 488 | on_width_changed (glade_xml_get_widget (xml, "width"), NULL); 489 | on_resolution_changed (glade_xml_get_widget (xml, "resolution"), NULL); 490 | on_timestep_changed (glade_xml_get_widget (xml, "timestep"), NULL); 491 | on_time_factor_changed (glade_xml_get_widget (xml, "time_factor"), NULL); 492 | on_max_timestep_changed (glade_xml_get_widget (xml, "max_timestep"), NULL); 493 | on_last_timestep_changed (glade_xml_get_widget (xml, "last_timestep"), NULL); 494 | on_xdisplay_toggled (glade_xml_get_widget (xml, "xdisplay"), NULL); 495 | on_textdisplay_toggled (glade_xml_get_widget (xml, "textdisplay"), NULL); 496 | on_remote_check_toggled (glade_xml_get_widget (xml, "remote_check"), NULL); 497 | on_ssh_item_activate (NULL, NULL); 498 | on_remote_host_changed (glade_xml_get_widget (xml, "remote_host"), NULL); 499 | on_mpirun_changed (glade_xml_get_widget (xml, "mpirun"), NULL); 500 | on_num_cpus_changed (glade_xml_get_widget (xml, "num_cpus"), NULL); 501 | on_3d_activate (NULL, NULL); 502 | 503 | /* Off we go! */ 504 | gtk_main(); 505 | 506 | return 0; 507 | }