[PATCH 3/3] Compile subsurface with gtk3

Linus Torvalds torvalds at linux-foundation.org
Sun Jan 27 16:54:33 PST 2013


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Sun, 27 Jan 2013 16:40:01 -0800
Subject: [PATCH 3/3] Compile subsurface with gtk3

This makes us use gtk3.  There's two #if's in the source code, and
there's the Makefile changes, both now hard-coded to gtk3.  But if you
edit the Makefile to not have the -DCOMPILE_FOR_GTK3 and to look up the
gtk-2 libraries and include files, it uses the gtk2 code.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

As mentioned, the Makefile now needs to be changed to compile for gtk2. 
But apart from the pkg-config setting and the -DCOMPILE_FOR_GTK3, it 
should all "just work".

Even the -DCOMPILE_FOR_GTK3 part could probably be done with some kind of 
GTK version number check.

 Makefile          | 10 +++----
 display-gtk.h     |  1 +
 download-dialog.c |  2 +-
 equipment.c       | 25 ++++++++++--------
 gtk-gui.c         | 78 ++++++++++++++++++++++++++++++++++++++++---------------
 info.c            | 16 ++++++------
 planner.c         |  4 +--
 7 files changed, 88 insertions(+), 48 deletions(-)

diff --git a/Makefile b/Makefile
index 8ddce2696f23..c8f693d26c96 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION=2.1
 
 CC=gcc
-CFLAGS=-Wall -Wno-pointer-sign -g $(CLCFLAGS) -DGSEAL_ENABLE
+CFLAGS=-Wall -Wno-pointer-sign -g $(CLCFLAGS) -DGSEAL_ENABLE -DGDK_DISABLE_DEPRECATION_WARNINGS -DCOMPILE_FOR_GTK3
 INSTALL=install
 PKGCONFIG=pkg-config
 XML2CONFIG=xml2-config
@@ -82,7 +82,7 @@ endif
 # about it if it doesn't.
 LIBUSB = $(shell $(PKGCONFIG) --libs libusb-1.0 2> /dev/null)
 
-LIBGTK = $(shell $(PKGCONFIG) --libs gtk+-2.0 glib-2.0)
+LIBGTK = $(shell $(PKGCONFIG) --libs gtk+-3.0 glib-2.0)
 LIBDIVECOMPUTERCFLAGS = $(LIBDIVECOMPUTERINCLUDES)
 LIBDIVECOMPUTER = $(LIBDIVECOMPUTERARCHIVE) $(LIBUSB)
 
@@ -90,10 +90,10 @@ LIBXML2 = $(shell $(XML2CONFIG) --libs)
 LIBXSLT = $(shell $(XSLCONFIG) --libs)
 XML2CFLAGS = $(shell $(XML2CONFIG) --cflags)
 GLIB2CFLAGS = $(shell $(PKGCONFIG) --cflags glib-2.0)
-GTKCFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-2.0)
+GTKCFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
 CFLAGS += $(shell $(XSLCONFIG) --cflags)
-OSMGPSMAPFLAGS += $(shell $(PKGCONFIG) --cflags osmgpsmap)
-LIBOSMGPSMAP += $(shell $(PKGCONFIG) --libs osmgpsmap 2> /dev/null)
+#OSMGPSMAPFLAGS += $(shell $(PKGCONFIG) --cflags osmgpsmap)
+#LIBOSMGPSMAP += $(shell $(PKGCONFIG) --libs osmgpsmap 2> /dev/null)
 ifneq ($(strip $(LIBOSMGPSMAP)),)
 	GPSOBJ = gps.o
 	CFLAGS += -DHAVE_OSM_GPS_MAP
diff --git a/display-gtk.h b/display-gtk.h
index df29ff1d83a7..cee67f20dea5 100644
--- a/display-gtk.h
+++ b/display-gtk.h
@@ -72,6 +72,7 @@ extern GtkWidget *weightsystem_list_widget(int w_idx);
 extern GtkWidget *dive_list_create(void);
 extern void dive_list_destroy(void);
 
+extern const char *get_active_text(GtkComboBox *);
 extern gboolean icon_click_cb(GtkWidget *w, GdkEventButton *event, gpointer data);
 
 unsigned int amount_selected;
diff --git a/download-dialog.c b/download-dialog.c
index 73ed4bac974b..a244d6730984 100644
--- a/download-dialog.c
+++ b/download-dialog.c
@@ -330,7 +330,7 @@ static GtkComboBox *dc_device_selector(GtkWidget *vbox)
 	frame = gtk_frame_new(_("Device or mount point"));
 	gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 3);
 
-	combo_box = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(model), 0);
+	combo_box = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(model));
 	gtk_container_add(GTK_CONTAINER(frame), combo_box);
 
 	renderer = gtk_cell_renderer_text_new();
diff --git a/equipment.c b/equipment.c
index 416c2c8538fd..7886c59f0ccb 100644
--- a/equipment.c
+++ b/equipment.c
@@ -183,19 +183,24 @@ static gboolean match_desc(GtkTreeModel *model,	GtkTreePath *path,
 	return match;
 }
 
+/* Gtk made this "simpler" */
+const char *get_active_text(GtkComboBox *combo_box)
+{
+	return get_active_text(combo_box);
+}
+
 static int get_active_item(GtkComboBox *combo_box, GtkTreeIter *iter, GtkListStore *model)
 {
-	char *desc;
+	const char *desc;
 
 	if (gtk_combo_box_get_active_iter(combo_box, iter))
 		return TRUE;
 
-	desc = gtk_combo_box_get_active_text(combo_box);
+	desc = get_active_text(combo_box);
 
 	found_match = NULL;
 	gtk_tree_model_foreach(GTK_TREE_MODEL(model), match_desc, (void *)desc);
 
-	g_free(desc);
 	if (!found_match)
 		return FALSE;
 
@@ -232,10 +237,9 @@ static void cylinder_cb(GtkComboBox *combo_box, gpointer data)
 	 */
 	if (!cylinder->changed && cyl->type.description) {
 		int same;
-		char *desc = gtk_combo_box_get_active_text(combo_box);
+		const char *desc = get_active_text(combo_box);
 
 		same = !strcmp(desc, cyl->type.description);
-		g_free(desc);
 		if (same)
 			return;
 	}
@@ -276,10 +280,9 @@ static void weight_cb(GtkComboBox *combo_box, gpointer data)
 	 */
 	if (!ws_widget->changed && ws->description) {
 		int same;
-		char *desc = gtk_combo_box_get_active_text(combo_box);
+		const char *desc = get_active_text(combo_box);
 
 		same = !strcmp(desc, ws->description);
-		g_free(desc);
 		if (same)
 			return;
 	}
@@ -679,7 +682,7 @@ static void record_cylinder_changes(cylinder_t *cyl, struct cylinder_widget *cyl
 	if (!box)
 		return;
 
-	desc = gtk_combo_box_get_active_text(box);
+	desc = strdup(get_active_text(box));
 	volume = gtk_spin_button_get_value(cylinder->size);
 	pressure = gtk_spin_button_get_value(cylinder->pressure);
 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cylinder->pressure_button))) {
@@ -711,7 +714,7 @@ static void record_weightsystem_changes(weightsystem_t *ws, struct ws_widget *we
 	if (!box)
 		return;
 
-	desc = gtk_combo_box_get_active_text(box);
+	desc = get_active_text(box);
 	value = gtk_spin_button_get_value(weightsystem_widget->weight);
 
 	if (prefs.units.weight == LBS)
@@ -936,7 +939,7 @@ static void cylinder_widget(GtkWidget *vbox, struct cylinder_widget *cylinder, G
 	hbox = gtk_hbox_new(FALSE, 3);
 	gtk_container_add(GTK_CONTAINER(frame), hbox);
 
-	widget = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(model), 0);
+	widget = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(model));
 	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
 
 	cylinder->description = GTK_COMBO_BOX(widget);
@@ -1022,7 +1025,7 @@ static void ws_widget(GtkWidget *vbox, struct ws_widget *ws_widget, GtkListStore
 	hbox = gtk_hbox_new(FALSE, 3);
 	gtk_container_add(GTK_CONTAINER(frame), hbox);
 
-	widget = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(model), 0);
+	widget = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(model));
 	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
 
 	ws_widget->description = GTK_COMBO_BOX(widget);
diff --git a/gtk-gui.c b/gtk-gui.c
index 9f76d31cd1b2..748036b60b87 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -121,7 +121,7 @@ void report_error(GError* error)
 		error_count++;
 		char buffer[256];
 		snprintf(buffer, sizeof(buffer), _("Failed to open %i files."), error_count);
-		gtk_label_set(GTK_LABEL(error_label), buffer);
+		gtk_label_set_text(GTK_LABEL(error_label), buffer);
 	}
 }
 
@@ -397,7 +397,6 @@ GtkTreeViewColumn *tree_view_column(GtkWidget *tree_view, int index, const char
 		gtk_tree_view_column_set_cell_data_func(col, renderer, data_func, (void *)(long)index, NULL);
 	else
 		gtk_tree_view_column_add_attribute(col, renderer, "text", index);
-	gtk_object_set(GTK_OBJECT(renderer), "alignment", align, NULL);
 	switch (align) {
 	case PANGO_ALIGN_LEFT:
 		xalign = 0.0;
@@ -1006,6 +1005,7 @@ static void about_dialog(GtkWidget *w, gpointer data)
 {
 	const char *logo_property = NULL;
 	GdkPixbuf *logo = NULL;
+	GtkWidget * dialog;
 
 	if (need_icon) {
 		GtkWidget *image = gtk_image_new_from_file(subsurface_icon_name());
@@ -1015,6 +1015,12 @@ static void about_dialog(GtkWidget *w, gpointer data)
 			logo_property = "logo";
 		}
 	}
+	dialog = gtk_about_dialog_new();
+#if !GTK_CHECK_VERSION(2,24,0) /* F*cking gtk */
+	gtk_about_dialog_set_url_hook(about_dialog_link_cb, NULL, NULL);
+#else
+	g_signal_connect(GTK_ABOUT_DIALOG(dialog), "activate-link", G_CALLBACK(about_dialog_link_cb), NULL);
+#endif
 	gtk_show_about_dialog(NULL,
 		"title", _("About Subsurface"),
 		"program-name", "Subsurface",
@@ -1029,7 +1035,6 @@ static void about_dialog(GtkWidget *w, gpointer data)
 		/* Must be last: */
 		logo_property, logo,
 		NULL);
-	gtk_about_dialog_set_url_hook(about_dialog_link_cb, NULL, NULL);
 }
 
 static void view_list(GtkWidget *w, gpointer data)
@@ -1660,31 +1665,23 @@ static gboolean profile_tooltip (GtkWidget *widget, gint x, gint y,
 static double zoom_factor = 1.0;
 static int zoom_x = -1, zoom_y = -1;
 
-static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+static gboolean common_drawing_function(GtkWidget *widget, struct graphics_context *gc)
 {
 	int i = 0;
 	struct dive *dive = current_dive;
-	GtkAllocation allocation;
-	static struct graphics_context gc = { .printer = 0 };
 
-	/* the drawing area gives TOTAL width * height - x,y is used as the topx/topy offset
-	 * so effective drawing area is width-2x * height-2y */
-	gtk_widget_get_allocation(widget, &allocation);
-	gc.drawing_area.width = allocation.width;
-	gc.drawing_area.height = allocation.height;
-	gc.drawing_area.x = MIN(50,gc.drawing_area.width / 20.0);
-	gc.drawing_area.y = MIN(50,gc.drawing_area.height / 20.0);
+	gc->drawing_area.x = MIN(50,gc->drawing_area.width / 20.0);
+	gc->drawing_area.y = MIN(50,gc->drawing_area.height / 20.0);
 
-	gc.cr = gdk_cairo_create(gtk_widget_get_window(widget));
 	g_object_set(widget, "has-tooltip", TRUE, NULL);
-	g_signal_connect(widget, "query-tooltip", G_CALLBACK(profile_tooltip), &gc);
-	init_profile_background(&gc);
-	cairo_paint(gc.cr);
+	g_signal_connect(widget, "query-tooltip", G_CALLBACK(profile_tooltip), gc);
+	init_profile_background(gc);
+	cairo_paint(gc->cr);
 
 	if (zoom_factor > 1.0) {
 		double n = -(zoom_factor-1);
-		cairo_translate(gc.cr, n*zoom_x, n*zoom_y);
-		cairo_scale(gc.cr, zoom_factor, zoom_factor);
+		cairo_translate(gc->cr, n*zoom_x, n*zoom_y);
+		cairo_scale(gc->cr, zoom_factor, zoom_factor);
 	}
 
 	if (dive) {
@@ -1698,13 +1695,48 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer
 			tooltip_rects = NULL;
 		}
 		tooltips = 0;
-		plot(&gc, dive, SC_SCREEN);
+		plot(gc, dive, SC_SCREEN);
 	}
-	cairo_destroy(gc.cr);
 
 	return FALSE;
 }
 
+#ifdef COMPILE_FOR_GTK3
+
+static gboolean draw_callback(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+	guint width, height;
+	static struct graphics_context gc = { .printer = 0 };
+
+	width = gtk_widget_get_allocated_width(widget);
+	height = gtk_widget_get_allocated_height(widget);
+
+	gc.drawing_area.width = width;
+	gc.drawing_area.height = height;
+	gc.cr = cr;
+
+	return common_drawing_function(widget, &gc);
+}
+
+#else /* gtk2 */
+
+static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+	GtkAllocation allocation;
+	static struct graphics_context gc = { .printer = 0 };
+
+	/* the drawing area gives TOTAL width * height - x,y is used as the topx/topy offset
+	 * so effective drawing area is width-2x * height-2y */
+	gtk_widget_get_allocation(widget, &allocation);
+	gc.drawing_area.width = allocation.width;
+	gc.drawing_area.height = allocation.height;
+	gc.cr = gdk_cairo_create(gtk_widget_get_window(widget));
+
+	return common_drawing_function(widget, &gc);
+}
+
+#endif
+
 static void zoom_event(int x, int y, double inc)
 {
 	zoom_x = x;
@@ -1779,7 +1811,11 @@ GtkWidget *dive_profile_widget(void)
 
 	da = gtk_drawing_area_new();
 	gtk_widget_set_size_request(da, 350, 250);
+#ifdef COMPILE_FOR_GTK3
+	g_signal_connect(da, "draw", G_CALLBACK (draw_callback), NULL);
+#else
 	g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL);
+#endif
 	g_signal_connect(da, "button-press-event", G_CALLBACK(clicked), NULL);
 	g_signal_connect(da, "scroll-event", G_CALLBACK(scroll_event), NULL);
 	g_signal_connect(da, "button-release-event", G_CALLBACK(released), NULL);
diff --git a/info.c b/info.c
index 4104b5af54a9..6e17b19eddba 100644
--- a/info.c
+++ b/info.c
@@ -61,7 +61,7 @@ static const char *skip_space(const char *str)
  * The "master" string is the string of the current dive - we only consider it
  * changed if the old string is either empty, or matches that master string.
  */
-static char *get_combo_box_entry_text(GtkComboBoxEntry *combo_box, char **textp, const char *master)
+static char *get_combo_box_entry_text(GtkComboBox *combo_box, char **textp, const char *master)
 {
 	char *old = *textp;
 	const char *old_text;
@@ -202,7 +202,7 @@ static void info_menu_edit_cb(GtkMenuItem *menuitem, gpointer user_data)
 		edit_multi_dive_info(NULL);
 }
 
-static void add_menu_item(GtkMenu *menu, const char *label, const char *icon, void (*cb)(GtkMenuItem *, gpointer))
+static void add_menu_item(GtkMenuShell *menu, const char *label, const char *icon, void (*cb)(GtkMenuItem *, gpointer))
 {
 	GtkWidget *item;
 	if (icon) {
@@ -215,10 +215,10 @@ static void add_menu_item(GtkMenu *menu, const char *label, const char *icon, vo
 	}
 	g_signal_connect(item, "activate", G_CALLBACK(cb), NULL);
 	gtk_widget_show(item); /* Yes, really */
-	gtk_menu_prepend(menu, item);
+	gtk_menu_shell_prepend(menu, item);
 }
 
-static void populate_popup_cb(GtkTextView *entry, GtkMenu *menu, gpointer user_data)
+static void populate_popup_cb(GtkTextView *entry, GtkMenuShell *menu, gpointer user_data)
 {
 	if (amount_selected)
 		add_menu_item(menu, _("Edit"), GTK_STOCK_EDIT, info_menu_edit_cb);
@@ -251,7 +251,7 @@ static GtkEntry *single_text_entry(GtkWidget *box, const char *label, const char
 	return entry;
 }
 
-static GtkComboBoxEntry *text_entry(GtkWidget *box, const char *label, GtkListStore *completions, const char *text)
+static GtkComboBox *text_entry(GtkWidget *box, const char *label, GtkListStore *completions, const char *text)
 {
 	GtkEntry *entry;
 	GtkWidget *combo_box;
@@ -260,7 +260,7 @@ static GtkComboBoxEntry *text_entry(GtkWidget *box, const char *label, GtkListSt
 
 	gtk_box_pack_start(GTK_BOX(box), frame, FALSE, TRUE, 0);
 
-	combo_box = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(completions), 0);
+	combo_box = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(completions));
 	gtk_container_add(GTK_CONTAINER(frame), combo_box);
 
 	entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo_box)));
@@ -276,7 +276,7 @@ static GtkComboBoxEntry *text_entry(GtkWidget *box, const char *label, GtkListSt
 	gtk_entry_set_completion(entry, completion);
 	g_object_unref(completion);
 
-	return GTK_COMBO_BOX_ENTRY(combo_box);
+	return GTK_COMBO_BOX(combo_box);
 }
 
 enum writable {
@@ -518,7 +518,7 @@ static gboolean gps_changed(struct dive *dive, struct dive *master, const char *
 }
 
 struct dive_info {
-	GtkComboBoxEntry *location, *divemaster, *buddy, *rating, *suit, *viz;
+	GtkComboBox *location, *divemaster, *buddy, *rating, *suit, *viz;
 	GtkEntry *airtemp, *gps;
 	GtkTextView *notes;
 };
diff --git a/planner.c b/planner.c
index f58eec53788e..2193cc794f56 100644
--- a/planner.c
+++ b/planner.c
@@ -931,7 +931,7 @@ static void gas_changed_cb(GtkWidget *combo, gpointer data)
 	int o2, he;
 	int idx = data - NULL;
 
-	gastext = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
+	gastext = get_active_text(GTK_COMBO_BOX(combo));
 	/* stupidly this gets called for two reasons:
 	 * a) any keystroke into the entry field
 	 * b) mouse selection of a dropdown
@@ -1054,7 +1054,7 @@ static GtkWidget *add_gas_combobox_to_box(GtkWidget *box, const char *label, int
 		add_string_list_entry("EAN32", gas_model);
 		add_string_list_entry("EAN36 @ 1.6", gas_model);
 	}
-	combo = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(gas_model), 0);
+	combo = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(gas_model));
 	gtk_widget_add_events(combo, GDK_FOCUS_CHANGE_MASK);
 	g_signal_connect(gtk_bin_get_child(GTK_BIN(combo)), "focus-out-event", G_CALLBACK(gas_focus_out_cb), NULL + idx);
 	g_signal_connect(combo, "changed", G_CALLBACK(gas_changed_cb), NULL + idx);
-- 
1.8.1.1.271.g02f55e6



More information about the subsurface mailing list