changeset 24063:11de3fd58c59

merge of '8c50cfe68a5cab6521acc54fedd6797e6c8b863f' and 'b5edbb5c5168486c2c8c4b6bd01af85cbe56dc3c'
author SHiNE CsyFeK <csyfek@gmail.com>
date Fri, 19 Sep 2008 14:48:00 +0000
parents d57928c9dd8f (current diff) 8f30b1f32f46 (diff)
children a3cd7c3d9da1
files libpurple/protocols/qq/sys_msg.c libpurple/protocols/qq/sys_msg.h
diffstat 7 files changed, 116 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Sep 19 14:46:41 2008 +0000
+++ b/ChangeLog	Fri Sep 19 14:48:00 2008 +0000
@@ -11,6 +11,8 @@
 	* Fix a case where a conversation window could close unexpectedly.
 	* A mute sounds option has been added to the preferences window to
 	  help with discoverability.  CTRL+S is no longer bound to mute.
+	* Added ability to change the color of visited links (using the theme
+	  control plugin, or setting the color in ~/.gtkrc-2.0)
 
 	Finch:
 	* A new 'Nested Grouping' option in the 'Grouping' plugin. Group
--- a/libpurple/dnsquery.c	Fri Sep 19 14:46:41 2008 +0000
+++ b/libpurple/dnsquery.c	Fri Sep 19 14:48:00 2008 +0000
@@ -85,7 +85,7 @@
 	char hostname[512];
 	int port;
 } dns_params_t;
-#endif
+#endif /* end PURPLE_DNSQUERY_USE_FORK */
 
 static void
 purple_dnsquery_resolved(PurpleDnsQueryData *query_data, GSList *hosts)
@@ -108,6 +108,15 @@
 		}
 	}
 
+#ifdef PURPLE_DNSQUERY_USE_FORK
+	/*
+	 * Add the resolver to the list of available resolvers, and set it
+	 * to NULL so that it doesn't get destroyed along with the query_data
+	 */
+	free_dns_children = g_slist_prepend(free_dns_children, query_data->resolver);
+	query_data->resolver = NULL;
+#endif /* PURPLE_DNSQUERY_USE_FORK */
+
 	purple_dnsquery_destroy(query_data);
 }
 
@@ -126,10 +135,7 @@
 	PurpleDnsQueryUiOps *ops = purple_dnsquery_get_ui_ops();
 
 	if (ops && ops->resolve_host)
-	{
-		if (ops->resolve_host(query_data, purple_dnsquery_resolved, purple_dnsquery_failed))
-			return TRUE;
-	}
+		return ops->resolve_host(query_data, purple_dnsquery_resolved, purple_dnsquery_failed);
 
 	return FALSE;
 }
@@ -209,6 +215,16 @@
 	 * the result back to our parent, when finished.
 	 */
 	while (1) {
+		fd_set fds;
+		struct timeval tv = { .tv_sec = 20, .tv_usec = 0 };
+		FD_ZERO(&fds);
+		FD_SET(child_in, &fds);
+		rc = select(child_in + 1, &fds, NULL, NULL, &tv);
+		if (!rc) {
+			if (show_debug)
+				printf("dns[%d]: nobody needs me... =(\n", getpid());
+			break;
+		}
 		rc = read(child_in, &dns_params, sizeof(dns_params_t));
 		if (rc < 0) {
 			fprintf(stderr, "dns[%d]: Error: Could not read dns_params: "
@@ -402,9 +418,9 @@
 
 /**
  * @return TRUE if the request was sent succesfully.  FALSE
- * 		if the request could not be sent.  This isn't
- * 		necessarily an error.  If the child has expired,
- * 		for example, we won't be able to send the message.
+ *         if the request could not be sent.  This isn't
+ *         necessarily an error.  If the child has expired,
+ *         for example, we won't be able to send the message.
  */
 static gboolean
 send_dns_request_to_child(PurpleDnsQueryData *query_data,
@@ -476,13 +492,6 @@
 	query_data = queued_requests->data;
 	queued_requests = g_slist_delete_link(queued_requests, queued_requests);
 
-	if (purple_dnsquery_ui_resolve(query_data))
-	{
-		/* The UI is handling the resolve; we're done */
-		handle_next_queued_request();
-		return;
-	}
-
 	/*
 	 * If we have any children, attempt to have them perform the DNS
 	 * query.  If we're able to send the query then resolver will be
@@ -579,7 +588,7 @@
 		purple_dnsquery_failed(query_data, message);
 
 	} else if (rc == 0) {
-		g_snprintf(message, sizeof(message), _("EOF while reading from resolver process"));
+		g_snprintf(message, sizeof(message), _("Resolver process exited without answering our request"));
 		purple_dnsquery_failed(query_data, message);
 	}
 
@@ -594,6 +603,12 @@
 	query_data = data;
 	query_data->timeout = 0;
 
+	if (purple_dnsquery_ui_resolve(query_data))
+	{
+		/* The UI is handling the resolve; we're done */
+		return FALSE;
+	}
+
 	handle_next_queued_request();
 
 	return FALSE;
@@ -617,7 +632,7 @@
 	query_data->data = data;
 	query_data->resolver = NULL;
 
-	if (strlen(query_data->hostname) == 0)
+	if (*query_data->hostname == '\0')
 	{
 		purple_dnsquery_destroy(query_data);
 		g_return_val_if_reached(NULL);
@@ -895,10 +910,13 @@
 
 	if (query_data->resolver != NULL)
 		/*
-		 * Ideally we would tell our resolver child to stop resolving
-		 * shit and then we would add it back to the free_dns_children
-		 * linked list.  However, it's hard to tell children stuff,
-		 * they just don't listen.
+		 * This is only non-NULL when we're cancelling an in-progress
+		 * query.  Ideally we would tell our resolver child to stop
+		 * resolving shit and then we would add it back to the
+		 * free_dns_children linked list.  However, it's hard to tell
+		 * children stuff, they just don't listen.  So we'll just
+		 * kill the process and allow a new child to be started if we
+		 * have more stuff to resolve.
 		 */
 		purple_dnsquery_resolver_destroy(query_data->resolver);
 #elif defined _WIN32 /* end PURPLE_DNSQUERY_USE_FORK */
@@ -922,7 +940,7 @@
 		query_data->hosts = g_slist_remove(query_data->hosts, query_data->hosts->data);
 	}
 	g_free(query_data->error_message);
-#endif
+#endif /* end _WIN32 */
 
 	if (query_data->timeout > 0)
 		purple_timeout_remove(query_data->timeout);
@@ -976,5 +994,5 @@
 		purple_dnsquery_resolver_destroy(free_dns_children->data);
 		free_dns_children = g_slist_remove(free_dns_children, free_dns_children->data);
 	}
-#endif
+#endif /* end PURPLE_DNSQUERY_USE_FORK */
 }
--- a/libpurple/protocols/oscar/flap_connection.c	Fri Sep 19 14:46:41 2008 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Fri Sep 19 14:48:00 2008 +0000
@@ -158,8 +158,8 @@
 	gettimeofday(&now, NULL);
 
 	purple_debug_info("oscar", "Attempting to send %u queued SNACs and %u queued low-priority SNACs for %p\n",
-					  (conn->queued_snacs ? g_queue_get_length(conn->queued_snacs) : 0),
-					  (conn->queued_lowpriority_snacs ? g_queue_get_length(conn->queued_lowpriority_snacs) : 0),
+					  (conn->queued_snacs ? conn->queued_snacs->length : 0),
+					  (conn->queued_lowpriority_snacs ? conn->queued_lowpriority_snacs->length : 0),
 					  conn);
 	if (!conn->queued_snacs || flap_connection_send_snac_queue(conn, now, conn->queued_snacs)) {
 		if (!conn->queued_lowpriority_snacs || flap_connection_send_snac_queue(conn, now, conn->queued_lowpriority_snacs)) {
--- a/libpurple/proxy.c	Fri Sep 19 14:46:41 2008 +0000
+++ b/libpurple/proxy.c	Fri Sep 19 14:48:00 2008 +0000
@@ -212,19 +212,21 @@
 {
 	static PurpleProxyInfo info = {0, NULL, 0, NULL, NULL};
 	gboolean use_same_proxy = FALSE;
-	gchar *tmp, *err;
+	gchar *tmp, *err = NULL;
 
 	tmp = g_find_program_in_path("gconftool-2");
 	if (tmp == NULL)
 		return purple_global_proxy_get_info();
 
 	g_free(tmp);
+	tmp = NULL;
 
 	/* Check whether to use a proxy. */
 	if (!g_spawn_command_line_sync("gconftool-2 -g /system/proxy/mode",
 			&tmp, &err, NULL, NULL))
 		return purple_global_proxy_get_info();
 	g_free(err);
+	err = NULL;
 
 	if (!strcmp(tmp, "none\n")) {
 		info.type = PURPLE_PROXY_NONE;
@@ -239,6 +241,7 @@
 	}
 
 	g_free(tmp);
+	tmp = NULL;
 
 	/* Free the old fields */
 	if (info.host) {
@@ -258,28 +261,31 @@
 			&tmp, &err, NULL, NULL))
 		return purple_global_proxy_get_info();
 	g_free(err);
+	err = NULL;
 
 	if (!strcmp(tmp, "true\n"))
 		use_same_proxy = TRUE;
 	g_free(tmp);
+	tmp = NULL;
 
-	if (!use_same_proxy && !g_spawn_command_line_sync("gconftool-2 -g /system/proxy/socks_host",
+	if (!use_same_proxy) {
+		if (!g_spawn_command_line_sync("gconftool-2 -g /system/proxy/socks_host",
 			&info.host, &err, NULL, NULL))
-		return purple_global_proxy_get_info();
-	g_free(err);
-	g_strchomp(info.host);
+			return purple_global_proxy_get_info();
+		g_free(err);
+		err = NULL;
+	}
 
-	if (!use_same_proxy && *info.host != '\0') {
+	if(info.host != NULL)
+		g_strchomp(info.host);
+
+	if (!use_same_proxy && (info.host != NULL) && (*info.host != '\0')) {
 		info.type = PURPLE_PROXY_SOCKS5;
 		if (!g_spawn_command_line_sync("gconftool-2 -g /system/proxy/socks_port",
 				&tmp, &err, NULL, NULL))
 		{
 			g_free(info.host);
 			info.host = NULL;
-			g_free(info.username);
-			info.username = NULL;
-			g_free(info.password);
-			info.password = NULL;
 			return purple_global_proxy_get_info();
 		}
 		g_free(err);
@@ -291,6 +297,8 @@
 					&info.host, &err, NULL, NULL))
 			return purple_global_proxy_get_info();
 		g_free(err);
+		err = NULL;
+
 		/* If we get this far then we know we're using an HTTP proxy */
 		info.type = PURPLE_PROXY_HTTP;
 
@@ -310,11 +318,10 @@
 		{
 			g_free(info.host);
 			info.host = NULL;
-			g_free(info.username);
-			info.username = NULL;
 			return purple_global_proxy_get_info();
 		}
 		g_free(err);
+		err = NULL;
 		g_strchomp(info.username);
 
 		if (!g_spawn_command_line_sync("gconftool-2 -g /system/http_proxy/authentication_password",
@@ -327,6 +334,7 @@
 			return purple_global_proxy_get_info();
 		}
 		g_free(err);
+		err = NULL;
 		g_strchomp(info.password);
 
 		if (!g_spawn_command_line_sync("gconftool-2 -g /system/http_proxy/port",
--- a/pidgin/gtkimhtml.c	Fri Sep 19 14:46:41 2008 +0000
+++ b/pidgin/gtkimhtml.c	Fri Sep 19 14:48:00 2008 +0000
@@ -446,6 +446,20 @@
 	parent_style_set(widget, prev_style);
 }
 
+static void
+gtk_imhtml_set_link_color(GtkIMHtml *imhtml, GtkTextTag *tag)
+{
+	GdkColor *color = NULL;
+	gboolean visited = !!g_object_get_data(G_OBJECT(tag), "visited");
+	gtk_widget_style_get(GTK_WIDGET(imhtml), visited ? "hyperlink-visited-color" : "hyperlink-color", &color, NULL);
+	if (color) {
+		g_object_set(G_OBJECT(tag), "foreground-gdk", color, NULL);
+		gdk_color_free(color);
+	} else {
+		g_object_set(G_OBJECT(tag), "foreground", visited ? "#800000" : "blue", NULL);
+	}
+}
+
 static gint
 gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
 {
@@ -566,7 +580,6 @@
 	int x, y;
 	char *tip = NULL;
 	GSList *tags = NULL, *templist = NULL;
-	GdkColor *norm, *pre;
 	GtkTextTag *tag = NULL, *oldprelit_tag;
 	GtkTextChildAnchor* anchor;
 	gboolean hand = TRUE;
@@ -588,13 +601,15 @@
 		templist = templist->next;
 	}
 
-	if (tip) {
-		gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL);
+	if (tip && (!tag || !g_object_get_data(G_OBJECT(tag), "visited"))) {
 		GTK_IMHTML(imhtml)->prelit_tag = tag;
 		if (tag != oldprelit_tag) {
-			if (pre)
+			GdkColor *pre = NULL;
+			gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL);
+			if (pre) {
 				g_object_set(G_OBJECT(tag), "foreground-gdk", pre, NULL);
-			else
+				gdk_color_free(pre);
+			} else
 				g_object_set(G_OBJECT(tag), "foreground", "#70a0ff", NULL);
 		}
 	} else {
@@ -602,11 +617,7 @@
 	}
 
 	if ((oldprelit_tag != NULL) && (GTK_IMHTML(imhtml)->prelit_tag != oldprelit_tag)) {
-		gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL);
-		if (norm)
-			g_object_set(G_OBJECT(oldprelit_tag), "foreground-gdk", norm, NULL);
-		else
-			g_object_set(G_OBJECT(oldprelit_tag), "foreground", "blue", NULL);
+		gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), oldprelit_tag);
 	}
 
 	if (GTK_IMHTML(imhtml)->tip) {
@@ -670,12 +681,7 @@
 {
 	/* when leaving the widget, clear any current & pending tooltips and restore the cursor */
 	if (GTK_IMHTML(imhtml)->prelit_tag) {
-		GdkColor *norm;
-		gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL);
-		if (norm)
-			g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground-gdk", norm, NULL);
-		else
-			g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground", "blue", NULL);
+		gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), GTK_IMHTML(imhtml)->prelit_tag);
 		GTK_IMHTML(imhtml)->prelit_tag = NULL;
 	}
 
@@ -1482,6 +1488,10 @@
 	                                        _("Hyperlink color"),
 	                                        _("Color to draw hyperlinks."),
 	                                        GDK_TYPE_COLOR, G_PARAM_READABLE));
+	gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-visited-color",
+	                                        _("Hyperlink visited color"),
+	                                        _("Color to draw hyperlinks after it has been visited (or activated)."),
+	                                        GDK_TYPE_COLOR, G_PARAM_READABLE));
 	gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-prelight-color",
 	                                        _("Hyperlink prelight color"),
 	                                        _("Color to draw hyperlinks when mouse is over them."),
@@ -1679,20 +1689,24 @@
 struct url_data {
 	GObject *object;
 	gchar *url;
+	GtkTextTag *tag;
 };
 
 static void url_data_destroy(gpointer mydata)
 {
 	struct url_data *data = mydata;
 	g_object_unref(data->object);
+	g_object_unref(data->tag);
 	g_free(data->url);
 	g_free(data);
 }
 
-static void url_open(GtkWidget *w, struct url_data *data) {
+static void url_open(GtkWidget *w, struct url_data *data)
+{
 	if(!data) return;
 	g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url);
-
+	g_object_set_data(G_OBJECT(data->tag), "visited", GINT_TO_POINTER(TRUE));
+	gtk_imhtml_set_link_color(GTK_IMHTML(data->object), data->tag);
 }
 
 static void url_copy(GtkWidget *w, gchar *url) {
@@ -1706,7 +1720,8 @@
 }
 
 /* The callback for an event on a link tag. */
-static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) {
+static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused)
+{
 	GdkEventButton *event_button = (GdkEventButton *) event;
 	if (GTK_IMHTML(imhtml)->editable)
 		return FALSE;
@@ -1723,12 +1738,15 @@
 			g_object_ref(G_OBJECT(tag));
 			g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url"));
 			g_object_unref(G_OBJECT(tag));
+			g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE));
+			gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag);
 			return FALSE;
 		} else if(event_button->button == 3) {
 			GtkWidget *img, *item, *menu;
 			struct url_data *tempdata = g_new(struct url_data, 1);
 			tempdata->object = g_object_ref(imhtml);
 			tempdata->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url"));
+			tempdata->tag = g_object_ref(tag);
 
 			/* Don't want the tooltip around if user right-clicked on link */
 			if (GTK_IMHTML(imhtml)->tip_window) {
--- a/pidgin/gtkmenutray.c	Fri Sep 19 14:46:41 2008 +0000
+++ b/pidgin/gtkmenutray.c	Fri Sep 19 14:48:00 2008 +0000
@@ -84,6 +84,14 @@
 }
 
 static void
+pidgin_menu_tray_map(GtkWidget *widget)
+{
+	GTK_WIDGET_CLASS(parent_class)->map(widget);
+	gtk_container_add(GTK_CONTAINER(widget),
+			PIDGIN_MENU_TRAY(widget)->tray);
+}
+
+static void
 pidgin_menu_tray_finalize(GObject *obj)
 {
 	PidginMenuTray *tray = PIDGIN_MENU_TRAY(obj);
@@ -109,6 +117,7 @@
 pidgin_menu_tray_class_init(PidginMenuTrayClass *klass) {
 	GObjectClass *object_class = G_OBJECT_CLASS(klass);
 	GtkItemClass *item_class = GTK_ITEM_CLASS(klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 	GParamSpec *pspec;
 
 	parent_class = g_type_class_peek_parent(klass);
@@ -119,6 +128,8 @@
 	item_class->select = pidgin_menu_tray_select;
 	item_class->deselect = pidgin_menu_tray_deselect;
 
+	widget_class->map = pidgin_menu_tray_map;
+
 	pspec = g_param_spec_object("box", "The box",
 								"The box",
 								GTK_TYPE_BOX,
@@ -152,8 +163,6 @@
 		gtk_widget_set_size_request(widget, -1, height);
 	}
 
-	gtk_container_add(GTK_CONTAINER(menu_tray), menu_tray->tray);
-
 	gtk_widget_show(menu_tray->tray);
 }
 
--- a/pidgin/plugins/pidginrc.c	Fri Sep 19 14:46:41 2008 +0000
+++ b/pidgin/plugins/pidginrc.c	Fri Sep 19 14:48:00 2008 +0000
@@ -31,6 +31,7 @@
 	"/plugins/gtk/purplerc/color/GtkWidget::cursor-color",
 	"/plugins/gtk/purplerc/color/GtkWidget::secondary-cursor-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-color",
+	"/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-visited-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::send-name-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::receive-name-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::highlight-name-color",
@@ -40,6 +41,7 @@
 	"/plugins/gtk/purplerc/set/color/GtkWidget::cursor-color",
 	"/plugins/gtk/purplerc/set/color/GtkWidget::secondary-cursor-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-color",
+	"/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-visited-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::send-name-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::receive-name-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::highlight-name-color",
@@ -49,6 +51,7 @@
 	N_("Cursor Color"),
 	N_("Secondary Cursor Color"),
 	N_("Hyperlink Color"),
+	N_("Visited Hyperlink Color"),
 	N_("Sent Message Name Color"),
 	N_("Received Message Name Color"),
 	N_("Highlighted Message Name Color"),