pidgin/gtkimhtml.c

branch
cpw.qulogic.gtk3
changeset 32414
8c5d1edf9da2
parent 31310
7835bac46b07
parent 32413
00ad036bdf3d
child 32422
c215bc5d85e4
--- a/pidgin/gtkimhtml.c	Sun Jan 09 20:28:58 2011 +0000
+++ b/pidgin/gtkimhtml.c	Sun Jan 09 23:32:10 2011 +0000
@@ -422,7 +422,7 @@
 
 	/* Don't scroll here if we're in the middle of a smooth scroll */
 	if (scroll && imhtml->scroll_time == NULL &&
-	    GTK_WIDGET_REALIZED(imhtml))
+	    gtk_widget_get_realized(GTK_WIDGET(imhtml)))
 		gtk_imhtml_scroll_to_end(imhtml, FALSE);
 }
 
@@ -511,18 +511,20 @@
 gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
 {
 	PangoLayout *layout;
+	cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(imhtml->tip_window));
 
 	g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
 
 	layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
 
-	gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window,
-						GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window,
-						"tooltip", 0, 0, -1, -1);
-
-	gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL,
-					  FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout);
-
+	gtk_paint_flat_box (gtk_widget_get_style(imhtml->tip_window), cr,
+		GTK_STATE_NORMAL, GTK_SHADOW_OUT, imhtml->tip_window, "tooltip",
+		0, 0, -1, -1);
+
+	gtk_paint_layout (gtk_widget_get_style(imhtml->tip_window), cr,
+		GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL, 4, 4, layout);
+
+	cairo_destroy(cr);
 	g_object_unref(layout);
 	return FALSE;
 }
@@ -534,12 +536,15 @@
 	PangoFontMetrics *font_metrics;
 	PangoLayout *layout;
 	PangoFont *font;
-
+	GtkStyle *style = gtk_widget_get_style(imhtml->tip_window);
+	GtkAllocation allocation;
 	gint gap, x, y, h, w, scr_w, baseline_skip;
 
 	g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
 
-	if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) {
+	gtk_widget_get_allocation(GTK_WIDGET(imhtml), &allocation);
+
+	if (!imhtml->tip || !gtk_widget_is_drawable(GTK_WIDGET(imhtml))) {
 		imhtml->tip_timer = 0;
 		return FALSE;
 	}
@@ -563,11 +568,10 @@
 	gtk_widget_ensure_style (imhtml->tip_window);
 	layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
 	font = pango_context_load_font(pango_layout_get_context(layout),
-			      imhtml->tip_window->style->font_desc);
+	                               style->font_desc);
 
 	if (font == NULL) {
-		char *tmp = pango_font_description_to_string(
-					imhtml->tip_window->style->font_desc);
+		char *tmp = pango_font_description_to_string(style->font_desc);
 
 		purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip",
 			"pango_context_load_font() couldn't load font: '%s'\n",
@@ -592,8 +596,8 @@
 	h = 8 + baseline_skip;
 
 	gdk_window_get_pointer (NULL, &x, &y, NULL);
-	if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml)))
-		y += GTK_WIDGET(imhtml)->allocation.y;
+	if ((!gtk_widget_get_has_window(GTK_WIDGET(imhtml))))
+		y += allocation.y;
 
 	scr_w = gdk_screen_width();
 
@@ -633,7 +637,7 @@
 
 	oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag;
 
-	gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL);
+	gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(imhtml)), NULL, NULL, NULL);
 	gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET,
 	                                      event->x, event->y, &x, &y);
 	gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y);
@@ -761,6 +765,8 @@
 	return FALSE;
 }
 
+/* TODO: I think this can be removed for GTK+ 3.0... */
+#if 0
 static gint
 gtk_imhtml_expose_event (GtkWidget      *widget,
 			 GdkEventExpose *event)
@@ -788,7 +794,8 @@
 			gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor);
 			gdk_cairo_set_source_color(cr, &gcolor);
 		} else {
-			gdk_cairo_set_source_color(cr, &(widget->style->base[GTK_WIDGET_STATE(widget)]));
+			gdk_cairo_set_source_color(cr,
+				&(gtk_widget_get_style(widget)->base[gtk_widget_get_state(widget)]));
 		}
 
 		cairo_rectangle(cr,
@@ -894,6 +901,7 @@
 
 	return FALSE;
 }
+#endif
 
 
 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
@@ -1170,11 +1178,12 @@
 {
 	char *text;
 	GtkIMHtml *imhtml = data;
+	gint length = gtk_selection_data_get_length(selection_data);
 
 	if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
 		return;
 
-	if (imhtml->wbfo || selection_data->length <= 0) {
+	if (imhtml->wbfo || length <= 0) {
 		gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
 		return;
 	} else {
@@ -1198,13 +1207,13 @@
 		}
 #endif
 
-		text = g_malloc(selection_data->length + 1);
-		memcpy(text, selection_data->data, selection_data->length);
+		text = g_malloc(length + 1);
+		memcpy(text, gtk_selection_data_get_data(selection_data), length);
 		/* Make sure the paste data is null-terminated.  Given that
 		 * we're passed length (but assume later that it is
 		 * null-terminated), this seems sensible to me.
 		 */
-		text[selection_data->length] = '\0';
+		text[length] = '\0';
 	}
 
 #ifdef _WIN32
@@ -1215,10 +1224,10 @@
 	}
 #endif
 
-	if (selection_data->length >= 2 &&
+	if (length >= 2 &&
 		(*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) {
 		/* This is UTF-16 */
-		char *utf8 = utf16_to_utf8_with_bom_check(text, selection_data->length);
+		char *utf8 = utf16_to_utf8_with_bom_check(text, length);
 		g_free(text);
 		text = utf8;
 		if (!text) {
@@ -1579,7 +1588,8 @@
 
 	gobject_class->finalize = gtk_imhtml_finalize;
 	widget_class->drag_motion = gtk_text_view_drag_motion;
-	widget_class->expose_event = gtk_imhtml_expose_event;
+	/* TODO: I _think_ this should be removed for GTK+ 3.0 */
+	/*widget_class->expose_event = gtk_imhtml_expose_event;*/
 	parent_size_allocate = widget_class->size_allocate;
 	widget_class->size_allocate = gtk_imhtml_size_allocate;
 	parent_style_set = widget_class->style_set;
@@ -1641,20 +1651,20 @@
 	                                        TRUE, G_PARAM_READABLE));
 
 	binding_set = gtk_binding_set_by_class (parent_class);
-	gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
-	gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
-	gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
-	gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
-	gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
-	gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
 	binding_set = gtk_binding_set_by_class(klass);
-	gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK, "undo", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
-	gtk_binding_entry_add_signal (binding_set, GDK_F14, 0, "undo", 0);
-	gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format_function_clear", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "message_send", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "message_send", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK, "undo", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
+	gtk_binding_entry_add_signal (binding_set, GDK_KEY_F14, 0, "undo", 0);
+	gtk_binding_entry_add_signal(binding_set, GDK_KEY_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
 }
 
 static void gtk_imhtml_init (GtkIMHtml *imhtml)
@@ -1881,13 +1891,13 @@
 		/* can't accept any of the offered targets */
 	} else {
 		GtkWidget *source_widget;
-		suggested_action = context->suggested_action;
+		suggested_action = gdk_drag_context_get_suggested_action(context);
 		source_widget = gtk_drag_get_source_widget (context);
 		if (source_widget == widget) {
 			/* Default to MOVE, unless the user has
 			 * pressed ctrl or alt to affect available actions
 			 */
-			if ((context->actions & GDK_ACTION_MOVE) != 0)
+			if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0)
 				suggested_action = GDK_ACTION_MOVE;
 		}
 	}
@@ -1919,21 +1929,22 @@
 {
 	gchar **links;
 	gchar *link;
-	char *text = (char *)sd->data;
+	char *text = (char *) gtk_selection_data_get_data(sd);
 	GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer);
 	GtkTextIter iter;
 	gint i = 0;
+	gint length = gtk_selection_data_get_length(sd);
 
 	gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark);
 
-	if(gtk_imhtml_get_editable(imhtml) && sd->data){
+	if (gtk_imhtml_get_editable(imhtml) && text) {
 		switch (info) {
 		case GTK_IMHTML_DRAG_URL:
 			/* TODO: Is it really ok to change sd->data...? */
-			purple_str_strip_char((char *)sd->data, '\r');
-
-			links = g_strsplit((char *)sd->data, "\n", 0);
-			while((link = links[i]) != NULL){
+			purple_str_strip_char(text, '\r');
+
+			links = g_strsplit(text, "\n", 0);
+			while ((link = links[i]) != NULL) {
 				if (gtk_imhtml_is_protocol(link)) {
 					gchar *label;
 
@@ -1971,8 +1982,8 @@
 			 * See also the comment on text/html here:
 			 * http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html
 			 */
-			if (sd->length >= 2 && !g_utf8_validate(text, sd->length - 1, NULL)) {
-				utf8 = utf16_to_utf8_with_bom_check(text, sd->length);
+			if (length >= 2 && !g_utf8_validate(text, length - 1, NULL)) {
+				utf8 = utf16_to_utf8_with_bom_check(text, length);
 
 				if (!utf8) {
 					purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in drag_rcv_cb\n");
@@ -2001,7 +2012,8 @@
 			gtk_drag_finish(dc, FALSE, FALSE, t);
 			return;
 		}
-		gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
+		gtk_drag_finish(dc, TRUE,
+		                gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
 	} else {
 		gtk_drag_finish(dc, FALSE, FALSE, t);
 	}
@@ -2532,8 +2544,8 @@
 static gboolean smooth_scroll_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
-	GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
-	gdouble max_val = adj->upper - adj->page_size;
+	GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
+	gdouble max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
 	gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3);
 
 	g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE);
@@ -2556,9 +2568,10 @@
 static gboolean scroll_idle_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
-	GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
-	if(adj) {
-		gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
+	GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
+	if (adj) {
+		gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) -
+		                              gtk_adjustment_get_page_size(adj));
 	}
 	imhtml->scroll_src = 0;
 	return FALSE;
@@ -4216,9 +4229,14 @@
 
 	for (l = tags; l; l = l->next) {
 		GtkTextTag *tag = l->data;
-
-		if (tag->name && !strncmp(tag->name, prefix, len))
+		gchar *name = NULL;
+
+		g_object_get(G_OBJECT(tag), "name", &name, NULL);
+
+		if (name && !strncmp(name, prefix, len))
 			gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e);
+
+		g_free(name);
 	}
 
 	g_slist_free(tags);
@@ -4234,10 +4252,15 @@
 
 			for (l = tags; l; l = l->next) {
 				GtkTextTag *tag = l->data;
-
-				if (tag->name && !strncmp(tag->name, prefix, len))
+				gchar *name = NULL;
+
+				g_object_get(G_OBJECT(tag), "name", &name, NULL);
+
+				if (name && !strncmp(name, prefix, len))
 					gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e);
-			}
+
+				g_free(name);
+      }
 
 			g_slist_free(tags);
 		}
@@ -4357,11 +4380,16 @@
 				gtk_text_iter_begins_tag(start, tag) &&			/* the tag starts with the selection */
 				(!gtk_text_iter_has_tag(end, tag) ||			/* the tag ends within the selection */
 					gtk_text_iter_ends_tag(end, tag))) {
+			gchar *name = NULL;
+
+			g_object_get(G_OBJECT(tag), "name", &name, NULL);
 			gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end);
-			if (tag->name &&
-					strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) {
+
+			if (name && strncmp(name, "LINK ", 5) == 0 && imhtml->edit.link) {
 				gtk_imhtml_toggle_link(imhtml, NULL);
 			}
+
+			g_free(name);
 		}
 	}
 	g_slist_free(tags);
@@ -4583,27 +4611,32 @@
 
 	for (l = tags; l != NULL; l = l->next) {
 		GtkTextTag *tag = GTK_TEXT_TAG(l->data);
-
-		if (tag->name) {
-			if (strcmp(tag->name, "BOLD") == 0)
+		gchar *name = NULL;
+
+		g_object_get(G_OBJECT(tag), "name", &name, NULL);
+
+		if (name) {
+			if (strcmp(name, "BOLD") == 0)
 				imhtml->edit.bold = TRUE;
-			else if (strcmp(tag->name, "ITALICS") == 0)
+			else if (strcmp(name, "ITALICS") == 0)
 				imhtml->edit.italic = TRUE;
-			else if (strcmp(tag->name, "UNDERLINE") == 0)
+			else if (strcmp(name, "UNDERLINE") == 0)
 				imhtml->edit.underline = TRUE;
-			else if (strcmp(tag->name, "STRIKE") == 0)
+			else if (strcmp(name, "STRIKE") == 0)
 				imhtml->edit.strike = TRUE;
-			else if (strncmp(tag->name, "FORECOLOR ", 10) == 0)
-				imhtml->edit.forecolor = g_strdup(&(tag->name)[10]);
-			else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0)
-				imhtml->edit.backcolor = g_strdup(&(tag->name)[10]);
-			else if (strncmp(tag->name, "FONT FACE ", 10) == 0)
-				imhtml->edit.fontface = g_strdup(&(tag->name)[10]);
-			else if (strncmp(tag->name, "FONT SIZE ", 10) == 0)
-				imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10);
-			else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
+			else if (strncmp(name, "FORECOLOR ", 10) == 0)
+				imhtml->edit.forecolor = g_strdup(&(name)[10]);
+			else if (strncmp(name, "BACKCOLOR ", 10) == 0)
+				imhtml->edit.backcolor = g_strdup(&(name)[10]);
+			else if (strncmp(name, "FONT FACE ", 10) == 0)
+				imhtml->edit.fontface = g_strdup(&(name)[10]);
+			else if (strncmp(name, "FONT SIZE ", 10) == 0)
+				imhtml->edit.fontsize = strtol(&(name)[10], NULL, 10);
+			else if ((strncmp(name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
 				imhtml->edit.link = tag;
 		}
+
+		g_free(name);
 	}
 
 	g_slist_free(tags);
@@ -4894,6 +4927,8 @@
 	gtk_text_buffer_end_user_action(imhtml->text_buffer);
 }
 
+/* TODO: I think this can be removed for GTK+ 3.0... */
+#if 0
 static gboolean
 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
 {
@@ -4901,9 +4936,10 @@
 
 	return TRUE;
 }
+#endif
 
 /* In case the smiley gets removed from the imhtml before it gets removed from the queue */
-static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml)
+static void animated_smiley_destroy_cb(GtkWidget *widget, GtkIMHtml *imhtml)
 {
 	GList *l = imhtml->animations->head;
 	while (l) {
@@ -4998,7 +5034,9 @@
 		 * images, and ensures that they are handled by the image
 		 * itself, without propagating to the textview and causing
 		 * a complete refresh */
+		/* TODO: I think this should be removed for GTK+ 3.0?
 		g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
+		*/
 
 		gtk_widget_show(icon);
 		if (ebox)
@@ -5100,22 +5138,29 @@
 
 static const gchar *tag_to_html_start(GtkTextTag *tag)
 {
-	const gchar *name;
 	static gchar buf[1024];
-
-	name = tag->name;
+	gchar *name = NULL;
+
 	g_return_val_if_fail(name != NULL, "");
+	g_object_get(G_OBJECT(tag), "name", &name, NULL);
 
 	if (strcmp(name, "BOLD") == 0) {
+		g_free(name);
 		return "<b>";
 	} else if (strcmp(name, "ITALICS") == 0) {
+		g_free(name);
 		return "<i>";
 	} else if (strcmp(name, "UNDERLINE") == 0) {
+		g_free(name);
 		return "<u>";
 	} else if (strcmp(name, "STRIKE") == 0) {
+		g_free(name);
 		return "<s>";
 	} else if (strncmp(name, "LINK ", 5) == 0) {
 		char *tmp = g_object_get_data(G_OBJECT(tag), "link_url");
+
+		g_free(name);
+
 		if (tmp) {
 			g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp);
 			buf[sizeof(buf)-1] = '\0';
@@ -5125,18 +5170,29 @@
 		}
 	} else if (strncmp(name, "FORECOLOR ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]);
+
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]);
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "BACKGROUND ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]);
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "FONT FACE ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]);
+		g_free(name);
+
 		return buf;
 	} else if (strncmp(name, "FONT SIZE ", 10) == 0) {
 		g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]);
+		g_free(name);
+
 		return buf;
 	} else {
 		char *str = buf;
@@ -5199,6 +5255,7 @@
 		}
 
 		g_snprintf(str, sizeof(buf) - (str - buf), "'>");
+		g_free(name);
 
 		return (empty ? "" : buf);
 	}
@@ -5206,30 +5263,40 @@
 
 static const gchar *tag_to_html_end(GtkTextTag *tag)
 {
-	const gchar *name;
-
-	name = tag->name;
+	gchar *name;
+
 	g_return_val_if_fail(name != NULL, "");
+	g_object_get(G_OBJECT(tag), "name", &name, NULL);
 
 	if (strcmp(name, "BOLD") == 0) {
+		g_free(name);
 		return "</b>";
 	} else if (strcmp(name, "ITALICS") == 0) {
+		g_free(name);
 		return "</i>";
 	} else if (strcmp(name, "UNDERLINE") == 0) {
+		g_free(name);
 		return "</u>";
 	} else if (strcmp(name, "STRIKE") == 0) {
+		g_free(name);
 		return "</s>";
 	} else if (strncmp(name, "LINK ", 5) == 0) {
+		g_free(name);
 		return "</a>";
 	} else if (strncmp(name, "FORECOLOR ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else if (strncmp(name, "BACKGROUND ", 10) == 0) {
+		g_free(name);
 		return "</body>";
 	} else if (strncmp(name, "FONT FACE ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else if (strncmp(name, "FONT SIZE ", 10) == 0) {
+		g_free(name);
 		return "</font>";
 	} else {
 		const char *props[] = {"weight-set", "foreground-set", "background-set",
@@ -5242,6 +5309,8 @@
 				return "</span>";
 		}
 
+		g_free(name);
+
 		return "";
 	}
 }

mercurial