gcompat: provide backwards compatible functions for older gtk versions

Attempt to do something that'll work equally well across gtk versions,
to improve the supported range.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/Makefile b/Makefile
index 50b827b..390d969 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,8 @@
 GTK_CFLAGS = `pkg-config --cflags gtk+-2.0 gthread-2.0`
 GTK_LDFLAGS = `pkg-config --libs gtk+-2.0 gthread-2.0`
 
+GTK_CFLAGS += -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED
+
 SOURCE := gettime.c ioengines.c init.c stat.c log.c time.c filesetup.c \
 		eta.c verify.c memory.c io_u.c parse.c mutex.c options.c \
 		lib/rbtree.c smalloc.c filehash.c profile.c debug.c lib/rand.c \
@@ -70,7 +72,7 @@
 OBJS = $(SOURCE:.c=.o)
 FIO_OBJS = $(OBJS) fio.o
 GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o gerror.o \
-			gclient.o
+			gclient.o gcompat.o
 
 T_SMALLOC_OBJS = t/stest.o
 T_SMALLOC_OBJS += mutex.o smalloc.o t/log.o
@@ -114,6 +116,9 @@
 .c.o: .depend FORCE
 	$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
 
+gcompat.o: gcompat.c gcompat.h
+	$(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c gcompat.c
+
 goptions.o: goptions.c goptions.h
 	$(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c goptions.c
 
diff --git a/gclient.c b/gclient.c
index 0a7d1df..67ec18c 100644
--- a/gclient.c
+++ b/gclient.c
@@ -578,7 +578,7 @@
 
 	gdk_threads_enter();
 
-	gtk_combo_box_append_text(GTK_COMBO_BOX(ge->eta.names), (gchar *) o->name);
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ge->eta.names), (gchar *) o->name);
 	gtk_combo_box_set_active(GTK_COMBO_BOX(ge->eta.names), 0);
 
 	sprintf(tmp, "%s %s", o->odirect ? "direct" : "buffered", ddir_str(o->td_ddir));
diff --git a/gcompat.c b/gcompat.c
new file mode 100644
index 0000000..f691ec1
--- /dev/null
+++ b/gcompat.c
@@ -0,0 +1,35 @@
+#include <gtk/gtk.h>
+
+#include "gcompat.h"
+
+#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 24
+
+GtkWidget *gtk_combo_box_text_new(void)
+{
+	return gtk_combo_box_new();
+}
+
+void gtk_combo_box_text_append_text(GtkComboBoxText *combo_box,
+				    const gchar *text)
+{
+	gtk_combo_box_append_text(GTK_COMBO_BOX(combo_box), text);
+}
+
+void gtk_combo_box_text_insert_text(GtkComboBoxText *combo_box, gint position,
+				    const gchar *text)
+{
+	gtk_combo_box_insert_text(GTK_COMBO_BOX(combo_box), position, text);
+}
+
+void gtk_combo_box_text_prepend_text(GtkComboBoxText *combo_box,
+				     const gchar *text)
+{
+	gtk_combo_box_prepend_text(GTK_COMBO_BOX(combo_box), text);
+}
+
+gchar *gtk_combo_box_text_get_active_text(GtkComboBoxText *combo_box)
+{
+	return gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo_box));
+}
+
+#endif
diff --git a/gcompat.h b/gcompat.h
new file mode 100644
index 0000000..9f6f1f6
--- /dev/null
+++ b/gcompat.h
@@ -0,0 +1,27 @@
+#ifndef GFIO_GTK_COMPAT
+#define GFIO_GTK_COMPAT
+
+#include <gtk/gtk.h>
+
+#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 24
+struct GtkComboBoxText;
+typedef GtkComboBox GtkComboBoxText;
+GtkWidget *gtk_combo_box_text_new(void);
+GtkWidget *gtk_combo_box_text_new_with_entry(void);
+void gtk_combo_box_text_append_text(GtkComboBoxText *combo_box, const gchar *text);
+void gtk_combo_box_text_insert_text(GtkComboBoxText *combo_box, gint position, const gchar *text);
+void gtk_combo_box_text_prepend_text(GtkComboBoxText *combo_box, const gchar *text);
+void gtk_combo_box_text_remove(GtkComboBoxText *combo_box, gint position);
+gchar *gtk_combo_box_text_get_active_text  (GtkComboBoxText *combo_box);
+
+#define GTK_COMBO_BOX_TEXT	GTK_COMBO_BOX
+#endif /* GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 24 */
+
+#if GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 14
+static inline GtkWidget *gtk_dialog_get_content_area(GtkDialog *dialog)
+{
+	return dialog->vbox;
+}
+#endif
+
+#endif
diff --git a/gerror.c b/gerror.c
index c0a4679..98b51a8 100644
--- a/gerror.c
+++ b/gerror.c
@@ -40,7 +40,7 @@
 	} else {
 		char buffer[256];
 		snprintf(buffer, sizeof(buffer), "Failed to open file.");
-		gtk_label_set(GTK_LABEL(ui->error_label), buffer);
+		gtk_label_set_text(GTK_LABEL(ui->error_label), buffer);
 	}
 }
 
diff --git a/gfio.c b/gfio.c
index 253d1fe..1ee2745 100644
--- a/gfio.c
+++ b/gfio.c
@@ -499,7 +499,7 @@
 	 * or not. Show it if we are a localhost and using network,
 	 * or using a socket.
 	 */
-	ctext = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw->combo));
+	ctext = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(cw->combo));
 	if (!ctext || !strncmp(ctext, "IPv4", 4) || !strncmp(ctext, "IPv6", 4))
 		uses_net = 1;
 	g_free(ctext);
@@ -538,8 +538,7 @@
 			GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
 
 	frame = gtk_frame_new("Hostname / socket name");
-	/* gtk_dialog_get_content_area() is 2.14 and newer */
-	vbox = GTK_DIALOG(dialog)->vbox;
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
 	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
 
 	box = gtk_vbox_new(FALSE, 6);
@@ -568,10 +567,10 @@
 	hbox = gtk_hbox_new(TRUE, 4);
 	gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
 
-	cw.combo = gtk_combo_box_new_text();
-	gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "IPv4");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "IPv6");
-	gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "local socket");
+	cw.combo = gtk_combo_box_text_new();
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "IPv4");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "IPv6");
+	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "local socket");
 	gtk_combo_box_set_active(GTK_COMBO_BOX(cw.combo), 0);
 
 	gtk_container_add(GTK_CONTAINER(hbox), cw.combo);
@@ -605,7 +604,7 @@
 	ge->host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry)));
 	ge->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
 
-	typeentry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw.combo));
+	typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(cw.combo));
 	if (!typeentry || !strncmp(typeentry, "IPv4", 4))
 		ge->type = Fio_client_ipv4;
 	else if (!strncmp(typeentry, "IPv6", 4))
@@ -969,7 +968,7 @@
 {
 	struct gui *ui = (struct gui *) data;
 
-	gtk_widget_ref(ui->log_tree);
+	g_object_ref(G_OBJECT(ui->log_tree));
 	gtk_container_remove(GTK_CONTAINER(w), ui->log_tree);
 	gtk_widget_destroy(w);
 	ui->log_view = NULL;
@@ -993,12 +992,12 @@
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
 	box = gtk_hbox_new(TRUE, 0);
-	gtk_box_pack_start_defaults(GTK_BOX(box), ui->log_tree);
+	gtk_box_pack_start(GTK_BOX(box), ui->log_tree, TRUE, TRUE, 0);
 	g_signal_connect(box, "destroy", G_CALLBACK(view_log_destroy), ui);
 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), box);
 
 	vbox = gtk_vbox_new(TRUE, 5);
-	gtk_box_pack_start_defaults(GTK_BOX(vbox), scroll);
+	gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
 
 	gtk_container_add(GTK_CONTAINER(win), vbox);
 	gtk_widget_show_all(win);
@@ -1118,7 +1117,8 @@
 		NULL);
 
 	frame = gtk_frame_new("Graphing");
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
 	vbox = gtk_vbox_new(FALSE, 6);
 	gtk_container_add(GTK_CONTAINER(frame), vbox);
 
@@ -1150,7 +1150,8 @@
 
 	spin_int = create_spinbutton(hbox, 100, 100000, gfio_client_ops.eta_msec);
 	frame = gtk_frame_new("Debug logging");
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
 	vbox = gtk_vbox_new(FALSE, 6);
 	gtk_container_add(GTK_CONTAINER(frame), vbox);
 
diff --git a/gfio.h b/gfio.h
index dd69c54..4d6d5d9 100644
--- a/gfio.h
+++ b/gfio.h
@@ -3,6 +3,7 @@
 
 #include <gtk/gtk.h>
 
+#include "gcompat.h"
 #include "stat.h"
 #include "thread_options.h"
 #include "ghelpers.h"
diff --git a/ghelpers.c b/ghelpers.c
index d9cc35a..d9380a2 100644
--- a/ghelpers.c
+++ b/ghelpers.c
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <gtk/gtk.h>
 
+#include "gcompat.h"
 #include "ghelpers.h"
 
 GtkWidget *new_combo_entry_in_frame(GtkWidget *box, const char *label)
@@ -9,7 +10,7 @@
 	GtkWidget *entry, *frame;
 
 	frame = gtk_frame_new(label);
-	entry = gtk_combo_box_new_text();
+	entry = gtk_combo_box_text_new();
 	gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
 	gtk_container_add(GTK_CONTAINER(frame), entry);
 
@@ -22,7 +23,7 @@
 
 	frame = gtk_frame_new(label);
 	entry = gtk_entry_new();
-	gtk_entry_set_editable(GTK_ENTRY(entry), 0);
+	gtk_editable_set_editable(GTK_EDITABLE(entry), 0);
 	gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
 	gtk_container_add(GTK_CONTAINER(frame), entry);
 
diff --git a/goptions.c b/goptions.c
index b7239a5..e74eb12 100644
--- a/goptions.c
+++ b/goptions.c
@@ -221,7 +221,7 @@
 	gopt_mark_index(gjv, &s->gopt, idx, GOPT_STR);
 	if (text)
 		gtk_entry_set_text(GTK_ENTRY(s->entry), text);
-	gtk_entry_set_editable(GTK_ENTRY(s->entry), 1);
+	gtk_editable_set_editable(GTK_EDITABLE(s->entry), 1);
 
 	if (o->def)
 		gtk_entry_set_text(GTK_ENTRY(s->entry), o->def);
@@ -272,7 +272,7 @@
 	else
 		label = gtk_label_new(o->lname);
 
-	c->combo = gtk_combo_box_new_text();
+	c->combo = gtk_combo_box_text_new();
 	gopt_mark_index(gjv, &c->gopt, idx, type);
 	g_signal_connect(G_OBJECT(c->combo), "destroy", G_CALLBACK(gopt_combo_destroy), c);
 
@@ -295,7 +295,7 @@
 	i = 0;
 	vp = &o->posval[0];
 	while (vp->ival) {
-		gtk_combo_box_append_text(GTK_COMBO_BOX(c->combo), vp->ival);
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(c->combo), vp->ival);
 		if (o->def && !strcmp(vp->ival, o->def))
 			active = i;
 		if (text && !strcmp(vp->ival, text))
@@ -322,7 +322,7 @@
 	i = 0;
 	vp = &o->posval[0];
 	while (vp->ival) {
-		gtk_combo_box_append_text(GTK_COMBO_BOX(c->combo), vp->ival);
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(c->combo), vp->ival);
 		if (ip && vp->oval == *ip)
 			active = i;
 		vp++;
@@ -734,10 +734,10 @@
 	g_signal_connect(G_OBJECT(g->spin), "wrapped", G_CALLBACK(gopt_str_val_spin_wrapped), g);
 	g_signal_connect(G_OBJECT(g->spin), "changed", G_CALLBACK(gopt_str_val_changed), g);
 
-	g->combo = gtk_combo_box_new_text();
+	g->combo = gtk_combo_box_text_new();
 	i = 0;
 	while (strlen(postfix[i])) {
-		gtk_combo_box_append_text(GTK_COMBO_BOX(g->combo), postfix[i]);
+		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(g->combo), postfix[i]);
 		i++;
 	}
 	g->maxindex = i - 1;
@@ -1058,7 +1058,7 @@
 	if (*p)
 		free(*p);
 
-	*p = strdup(gtk_combo_box_get_active_text(GTK_COMBO_BOX(c->combo)));
+	*p = strdup(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(c->combo)));
 }
 
 static void gopt_handle_combo_int_changed(struct gopt_job_view *gjv,
@@ -1189,7 +1189,8 @@
 	topnotebook = gtk_notebook_new();
 	gtk_notebook_set_scrollable(GTK_NOTEBOOK(topnotebook), 1);
 	gtk_notebook_popup_enable(GTK_NOTEBOOK(topnotebook));
-	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), topnotebook, TRUE, TRUE, 5);
+	vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+	gtk_box_pack_start(GTK_BOX(vbox), topnotebook, TRUE, TRUE, 5);
 
 	flist_for_each(entry, &gc->o_list) {
 		const char *name;