/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #+ #+ Glade / Gtk Programming #+ #+ Copyright (C) 2019 by Kevin C. O'Kane #+ #+ Kevin C. O'Kane #+ kc.okane@gmail.com #+ https://www.cs.uni.edu/~okane #+ http://threadsafebooks.com/ #+ #+ This program is free software; you can redistribute it and/or modify #+ it under the terms of the GNU General Public License as published by #+ the Free Software Foundation; either version 2 of the License, or #+ (at your option) any later version. #+ #+ This program is distributed in the hope that it will be useful, #+ but WITHOUT ANY WARRANTY; without even the implied warranty of #+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #+ GNU General Public License for more details. #+ #+ You should have received a copy of the GNU General Public License #+ along with this program; if not, write to the Free Software #+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #+ #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include #include #include #include #include #include #include #include #include #include #include // Make them global GtkWidget *window; GtkWidget *fixed1; GtkWidget *button1; GtkWidget *button2; GtkWidget *button3; GtkWidget *button4; GtkWidget *label1; GtkWidget *label2; GtkWidget *label3; GtkWidget *radio1; GtkWidget *radio2; GtkWidget *radio3; GtkWidget *check1; GtkWidget *toggle1; GtkWidget *spin1; GtkWidget *switch1; GtkWidget *combo1; GtkWidget *entry1; GtkWidget *color1; GtkWidget *file1; GtkWidget *font1; GtkWidget *volume1; GtkWidget *scroll1; GtkWidget *frame1; GtkWidget *frame2; GtkWidget *frame3; GtkWidget *frame4; GtkWidget *image1; GtkWidget *image2; GtkWidget *timer; GtkWidget *menu1; GtkWidget *new; GtkWidget *vc1; GtkWidget *prog1; GtkWidget *start1; GtkWidget *PingTime; GtkWidget *PingTimeDisplay; GtkBuilder *builder; GtkListStore *liststore1; GtkAdjustment *adjustment2; char *pingtotal; // pointer shared memory int *pingFlag; void on_destroy(); int countDownMax, countCurrent; int currentRow; char rows[5][10] = { "row 1", "row 2", "row 3", "row 4", "row 5" }; gboolean timer_handler(GtkWidget *); int main(int argc, char *argv[]) { gtk_init(&argc, &argv); // init Gtk //--------------------------------------------------------------------- // establish contact with xml code used to adjust widget settings //--------------------------------------------------------------------- builder = gtk_builder_new_from_file ("part1.glade"); window = GTK_WIDGET(gtk_builder_get_object(builder, "window")); g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), NULL); gtk_builder_connect_signals(builder, NULL); fixed1 = GTK_WIDGET(gtk_builder_get_object(builder, "fixed1")); button1 = GTK_WIDGET(gtk_builder_get_object(builder, "button1")); button2 = GTK_WIDGET(gtk_builder_get_object(builder, "button2")); button3 = GTK_WIDGET(gtk_builder_get_object(builder, "button3")); button4 = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); label1 = GTK_WIDGET(gtk_builder_get_object(builder, "label1")); label2 = GTK_WIDGET(gtk_builder_get_object(builder, "label2")); label3 = GTK_WIDGET(gtk_builder_get_object(builder, "label3")); radio1 = GTK_WIDGET(gtk_builder_get_object(builder, "radio1")); radio2 = GTK_WIDGET(gtk_builder_get_object(builder, "radio2")); radio3 = GTK_WIDGET(gtk_builder_get_object(builder, "radio3")); check1 = GTK_WIDGET(gtk_builder_get_object(builder, "check1")); toggle1 = GTK_WIDGET(gtk_builder_get_object(builder, "toggle1")); switch1 = GTK_WIDGET(gtk_builder_get_object(builder, "switch1")); combo1 = GTK_WIDGET(gtk_builder_get_object(builder, "combo1")); entry1 = GTK_WIDGET(gtk_builder_get_object(builder, "entry1")); spin1 = GTK_WIDGET(gtk_builder_get_object(builder, "spin1")); color1 = GTK_WIDGET(gtk_builder_get_object(builder, "color1")); font1 = GTK_WIDGET(gtk_builder_get_object(builder, "font1")); file1 = GTK_WIDGET(gtk_builder_get_object(builder, "file1")); volume1 = GTK_WIDGET(gtk_builder_get_object(builder, "volume1")); frame1 = GTK_WIDGET(gtk_builder_get_object(builder, "frame1")); frame2 = GTK_WIDGET(gtk_builder_get_object(builder, "frame2")); frame3 = GTK_WIDGET(gtk_builder_get_object(builder, "frame3")); frame4 = GTK_WIDGET(gtk_builder_get_object(builder, "frame4")); scroll1 = GTK_WIDGET(gtk_builder_get_object(builder, "scroll1")); image2 = GTK_WIDGET(gtk_builder_get_object(builder, "image2")); timer = GTK_WIDGET(gtk_builder_get_object(builder, "timer")); menu1 = GTK_WIDGET(gtk_builder_get_object(builder, "menu1")); new = GTK_WIDGET(gtk_builder_get_object(builder, "new")); vc1 = GTK_WIDGET(gtk_builder_get_object(builder, "vc1")); prog1 = GTK_WIDGET(gtk_builder_get_object(builder, "prog1")); start1 = GTK_WIDGET(gtk_builder_get_object(builder, "start1")); PingTime = GTK_WIDGET(gtk_builder_get_object(builder, "PingTime")); PingTimeDisplay = GTK_WIDGET(gtk_builder_get_object(builder, "PingTimeDisplay")); liststore1 = GTK_LIST_STORE(gtk_builder_get_object(builder, "liststore1")); adjustment2 = GTK_ADJUSTMENT(gtk_builder_get_object(builder, "adjustment2")); // Note include of at beginning pingtotal = mmap(NULL, 512, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); // shared memory strcpy(pingtotal,"Tot Play Time: "); pingFlag = mmap(NULL, 32, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); // shared memory *pingFlag = 1; /******************* struct GtkAdjustment { gdouble lower, gdouble upper, gdouble step_increment, gdouble page_increment, gdouble page_size}; ****************************/ /* alter the range of the scroll bar */ gtk_range_set_range (GTK_RANGE(scroll1), 0, 100); GdkColor color; // default background color color.red = 0xcccc; color.green = 0xcccc; color.blue = 0xd900; gtk_widget_modify_bg(GTK_WIDGET(window), GTK_STATE_NORMAL, &color); color.red = 0xaaaa; color.green = 0xaaaa; color.blue = 0xeeee; gtk_widget_modify_bg(frame1, GTK_STATE_NORMAL, &color); color.red = 0xaaaa; color.green = 0xeeee; color.blue = 0xaaaa; gtk_widget_modify_bg(frame2, GTK_STATE_NORMAL, &color); color.red = 0xeeee; color.green = 0xaaaa; color.blue = 0xaaaa; gtk_widget_modify_bg(frame3, GTK_STATE_NORMAL, &color); color.red = 0xeeee; color.green = 0xeeee; color.blue = 0xaaaa; gtk_widget_modify_bg(frame4, GTK_STATE_NORMAL, &color); image1 = NULL; // The following function returns an ID of the event that can be // used to destroy it. Not used here. guint ID = g_timeout_add_seconds(1, (GSourceFunc) timer_handler, timer); // Time units smaller than seconds are possible (higher overhead): // guint ID = g_timeout_add(250, (GSourceFunc) timer_handler, data_pointer); countCurrent = countDownMax = 0; // label3 & button4 scroll and background setup currentRow = 0; gtk_label_set_text (GTK_LABEL(label3), (const gchar* ) rows[currentRow]); color.red = 0xdddd; color.green = 0xcccc; color.blue = 0xd900; gtk_widget_modify_bg(label3, GTK_STATE_NORMAL, &color); // label background gtk_widget_set_events(button4, GDK_SCROLL_MASK); // allowed events. // see GdkEventScroll data // structure for valid elements gtk_widget_show(window); gtk_main(); return EXIT_SUCCESS; } //...................................................................................... void on_button1_clicked (GtkButton *b) { char tmp[128]; gdouble val = gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin1)); sprintf(tmp, "spin=%d", (int) val); gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) tmp); } void on_radio1_toggled(GtkRadioButton *b) { gboolean T = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b)); if (T) gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Radio 1 Active"); else gtk_label_set_text (GTK_LABEL(label2), (const gchar* ) "Radio 1 Not Active"); } void on_radio2_toggled(GtkRadioButton *b) { gboolean T = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b)); if (T) gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Radio 2 Active"); else gtk_label_set_text (GTK_LABEL(label2), (const gchar* ) "Radio 2 Not Active"); } void on_radio3_toggled(GtkRadioButton *b) { gboolean T = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b)); if (T) gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Radio 3 Active"); else gtk_label_set_text (GTK_LABEL(label2), (const gchar* ) "Radio 3 Not Active"); } void on_check1_toggled(GtkCheckButton *b) { gboolean T = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(b)); if (T) gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Check 1 Active"); else gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Check 1 Not Active"); } void on_toggle1_toggled(GtkToggleButton *b) { gboolean T = gtk_toggle_button_get_active(b); if (T) gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Toggle 1 Active"); else gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Toggle 1 Not Active"); } void on_switch1_state_set (GtkSwitch *s) { gboolean T = gtk_switch_get_active(s); if (T) gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Switch 1 Active"); else gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) "Switch 1 Not Active"); } void on_combo1_changed(GtkComboBox *c) { printf("combo1 changed entered\n"); } void on_color1_color_set (GtkColorButton *c) { GdkRGBA color; gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(c), &color); printf("red %f\n", color.red); printf("green %f\n", color.green); printf("blue %f\n", color.blue); printf("alpha %f\n\n", color.alpha); /* just for fun, lets change the scrollbar background */ gtk_widget_override_background_color (scroll1, GTK_STATE_FLAG_NORMAL, &color); } void on_file1_file_set(GtkFileChooserButton *f) { printf("file name = %s\n", gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(f)) ); printf("folder name = %s\n", gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(f)) ); } void on_font1_font_set(GtkFontButton *f1) { printf("font name = %s\n", gtk_font_button_get_font_name (f1) ); } void on_volume1_value_changed (GtkVolumeButton *v1) { /******************************************************************* The function: void gtk_scale_button_set_value (GtkScaleButton *, gdouble) can be used to set the volume control to a particular value. ********************************************************************/ printf("volume scale = %f\n", gtk_scale_button_get_value(GTK_SCALE_BUTTON(v1)) ); } void on_scroll1_value_changed(GtkRange *r) { gdouble x = gtk_range_get_value (r); printf("scroll = %d\n", (int) x ); } void on_entry1_changed(GtkEntry *e) { char tmp[128]; sprintf(tmp, "entry=%s", gtk_entry_get_text(e)); gtk_label_set_text (GTK_LABEL(label1), (const gchar* ) tmp); } void on_button2_clicked(GtkButton *b) { gtk_editable_delete_text (GTK_EDITABLE(entry1), 0, -1); } /*------------------------------------------------- void on_button3_clicked(GtkButton *b) { char filename[] = "prr.jpg"; int hor = 150, ver = 1; if (image1) gtk_container_remove (GTK_CONTAINER (fixed1), image1); // remove old slide gtk_widget_hide(image2); image1 = gtk_image_new_from_file (filename); gtk_container_add (GTK_CONTAINER (fixed1), image1); gtk_widget_show(image1); gtk_fixed_move (GTK_FIXED(fixed1), image1, hor, ver); } -------------------------------------------------*/ void on_button3_clicked(GtkButton *b) { char filename[] = "nya.jpg"; char cmd[2048]; FILE *f1; int j, h, v, hor = 150, ver = 1; if (image1) gtk_container_remove (GTK_CONTAINER (fixed1), image1); // remove old slide gtk_widget_hide(image2); // --------------------------------------------------------------- // get dimensions of image. identify() is part of ImageMagick // --------------------------------------------------------------- sprintf(cmd, "identify -format %%wx%%h \"%s\"\n", filename); f1 = popen(cmd, "r"); strcpy(cmd,""); fgets(cmd, 512, f1); fclose (f1); h = v = 1; if (strlen(cmd)) { for (j=0; jbutton); if (event->button < 3 ) return FALSE; // left or center click - continue processing countDownMax = countCurrent = 0; gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(prog1), (gdouble) 0.00 ); return TRUE; // stop processing of this click } gboolean on_button4_scroll_event(GtkButton *b, GdkEventScroll *e) { // see docs: GdkEventScroll data structure for valid elements // see above: gtk_widget_set_events(button4,GDK_SCROLL_MASK); if (e->direction == 1) { // down if (currentRow < 4) { currentRow ++; gtk_label_set_text (GTK_LABEL(label3), (const gchar* ) rows[currentRow]); return TRUE; } return TRUE; } else { // up if (currentRow > 0) { currentRow --; gtk_label_set_text (GTK_LABEL(label3), (const gchar* ) rows[currentRow]); return TRUE; } return TRUE; } return TRUE; } void on_PingTime_clicked (GtkButton *b) { pid_t i = fork(); if (i) return; // parent task returns FILE *f1 = popen("ping -c 10 www.cs.uni.edu", "r"); if (f1 == NULL) exit(1); while (1) { char name[512]; char * p1; if (*pingFlag == 0) { fclose(f1); exit(0); } if (fgets(name, 512, f1) == NULL) { strcpy(pingtotal, "done"); fclose(f1); exit(0); } p1 = strstr(name, "time="); if (p1 == NULL) continue; // first line has no "time=" printf("ping result=%s\n", p1); strcpy(pingtotal, p1); } } void on_destroy() { *pingFlag = 0; // note dereference operator gtk_main_quit(); }