Hooking it All Together

This should really be titled "Hooking it All Together with the main() function" because that's where it's all tied together. Yes, there are other important subroutines, such as the message handlers, but we'll get to them shortly. First, let's look at the key portions of main() which, as you know, is the heart of any and all C programs.


// =========gtk windowing main followsint main(int argc, char *argv[]){ GtkBuilder *builder; GtkWidget *window;
gtk_init(&argc, &argv); // mandatory initialization of the GTK functions if(0==Initialize_data_arrays()) // initialize data arrays {fprintf(stderr, "Error initializing data arrays.\n");} builder = gtk_builder_new(); // sets up to use the GTK display functions.to build the GLADE displays // load the GTK interface if(0 == gtk_builder_add_from_file (builder, "../window_main7.glade", &err)) { // Print out the error. You can use GLib's message logging fprintf(stderr, "Error adding build from file. Error: %s\n", err->message); // Your error handling code goes here } // Instantiate the main window window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main")); if (NULL==window){fprintf(stderr, "Unable to find object with id \"window_main\"\n");} global_window_main=window; // Instantiate the status display window status_display_win = GTK_WIDGET(gtk_builder_get_object(builder, "status_display_win")); if (NULL==status_display_win){fprintf(stderr, "Unable to find object with id \"status_display_win\"\n");} status_display_area = GTK_WIDGET(gtk_builder_get_object(builder, "status_display_area")); if (NULL==status_display_area){fprintf(stderr, "Unable to find object with id \"status_display_area\"\n");}

Now it's time to store pointers to all the widgets you build in your GLADE displays

// connect the other callback signals g_lbl_hello = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_hello")); g_lbl_count = GTK_WIDGET(gtk_builder_get_object(builder, "lbl_count")); display_update_lbl = GTK_WIDGET(gtk_builder_get_object(builder, "display_update_label")); label_ptr_array[1].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_01_direction")); label_ptr_array[2].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_02_direction")); label_ptr_array[3].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_03_direction")); label_ptr_array[4].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_04_direction")); label_ptr_array[5].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_05_direction")); label_ptr_array[6].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_06_direction")); label_ptr_array[7].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_07_direction")); label_ptr_array[0].block_direction_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_00_direction")); label_ptr_array[0].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_00_pwr")); label_ptr_array[1].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_01_pwr")); label_ptr_array[2].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_02_pwr")); label_ptr_array[3].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_03_pwr")); label_ptr_array[4].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_04_pwr")); label_ptr_array[5].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_05_pwr")); label_ptr_array[6].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_06_pwr")); label_ptr_array[7].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_07_pwr")); label_ptr_array[8].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_08_pwr")); label_ptr_array[9].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_09_pwr")); label_ptr_array[10].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_10_pwr")); label_ptr_array[11].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_11_pwr")); label_ptr_array[12].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_12_pwr")); label_ptr_array[13].pwr_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "block_13_pwr")); switch_ptr_array.switch_pwr_1 = GTK_SWITCH(gtk_builder_get_object(builder, "switch_pwr_1")); switch_ptr_array.switch_pwr_2 = GTK_SWITCH(gtk_builder_get_object(builder, "switch_pwr_2")); gtk_switch_set_state(switch_ptr_array.switch_pwr_1,FALSE); switch_ptr_array.main_pwr_1=FALSE; gtk_switch_set_state(switch_ptr_array.switch_pwr_2,FALSE); switch_ptr_array.main_pwr_2=FALSE; label_ptr_array[1].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_01")); label_ptr_array[2].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_02")); label_ptr_array[3].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_03")); label_ptr_array[4].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_04")); label_ptr_array[5].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_05")); label_ptr_array[6].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_06")); label_ptr_array[7].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_07")); label_ptr_array[0].status_label_ptr = (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "status_label_00")); gap_ptr_array[0].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_00_02")); // gap_00_02 gap_ptr_array[1].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_01_00")); gap_ptr_array[2].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_02_04")); gap_ptr_array[3].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_03_01")); gap_ptr_array[4].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_04_06")); gap_ptr_array[5].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_05_03")); gap_ptr_array[6].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_06_07")); gap_ptr_array[7].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_07_05")); gap_ptr_array[8].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_08_06")); gap_ptr_array[9].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_09_05")); gap_ptr_array[10].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_10_01")); gap_ptr_array[11].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_11_06")); gap_ptr_array[12].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_12_09")); gap_ptr_array[13].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_13_10")); gap_ptr_array[14].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_02_01")); gap_ptr_array[15].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_05_06")); gap_ptr_array[16].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "gap_06_05")); permit_array[0].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "siding_08_occ")); permit_array[1].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "siding_09_occ")); permit_array[2].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "siding_10_occ")); permit_array[3].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "cross_0201")); permit_array[4].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "cross_0506")); permit_array[5].label_ptr= (GtkLabel *) GTK_WIDGET(gtk_builder_get_object(builder, "cross_0605"));

Here's one way to end the program. (The other is in the display menu.)

// Register callback function for CTRL-C signal(SIGINT, my_handler); // set default status display mode alarm_display=GAPS_ONLY;

I mentioned various display callbacks above. Here they get implemented.

// ....insert code for the two main loop "embedded" windows // First, connect the layout status window function callbacks g_signal_connect(G_OBJECT(status_display_area), "draw", G_CALLBACK(status_display_callback),NULL); g_signal_connect(G_OBJECT(status_display_area), "destroy", G_CALLBACK(gtk_widget_destroy), NULL); // intercept the status display window's "X" (delete_event) click and // and "iconify" the window. Updating continues. Clicking on the // icon restores the window. g_signal_connect(G_OBJECT(status_display_win), "delete_event", G_CALLBACK(gtk_window_iconify), NULL);

Next, show data acquisition & update indicators in main window

progress_bar = GTK_WIDGET(gtk_builder_get_object(builder, "progress_bar")); gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progress_bar)); layout_widget=GTK_WIDGET(gtk_builder_get_object(builder, "layout_widget")); data_gather_label = GTK_WIDGET(gtk_builder_get_object(builder,"data_gather_label")); gtk_label_set_text(GTK_LABEL(data_gather_label), "Collecting data..."); gtk_builder_connect_signals(builder, NULL);

Next, add layout diagram to main window

GtkWidget *layout_miniature = GTK_WIDGET(gtk_builder_get_object(builder, "layout_miniature")); g_signal_connect(G_OBJECT(layout_miniature), "draw", G_CALLBACK(layout_display_callback),NULL); g_signal_connect(G_OBJECT(layout_miniature), "destroy", G_CALLBACK(gtk_widget_destroy), NULL);

Read raw data every 300 milliseconds

Run_data_loop=TRUE; data_acq_timeout_id=g_timeout_add(300, read_raw_data, progress_bar); time_tracker = g_timer_new ();

Show layout display & status display, update every 5 seconds

gtk_window_set_title(GTK_WINDOW(status_display_win), "Status"); gtk_widget_show_all(status_display_win); display_update_timeout_id=g_timeout_add(5000, display_layout_and_status_data,NULL); // clean up a bit g_object_unref(builder);

Initialize wiringPi and use BCM pin numbering (maybe later, for powerpack control)

if(wiringPiSetupGpio()<0){fprintf(stderr,"wiringPi GPIO pins setup failed.\n");}

display the window

gtk_widget_show(window); // ADDRESS is defined in the following map_pins_to_blocks(); printf("Press Ctrl-C to exit.\n"); turn_all_relays_off(); // initialize

Now enter the main loop, processing messages, until quit signal

gtk_main(); // main loop // no need for gtk_main_quit(); called from the main window menu.

End gracefully

turn_all_relays_off(); // reset all relays to OFF return 0;} // main()

Actually, that wasn't so bad. Once it's hooked up, the "gtk_main" loop takes care of what people are used to knowing as a windowing and messaging system. We'll next have a look at the message handling routines. wherein a few tricks lie.

Click here to see the details about Message Handling functions.