# HG changeset patch
# Node ID fa45badc4c2c
# Parent  d1f17ab61ecf
diff --git a/libpurple/protocols/ircv3/meson.build b/libpurple/protocols/ircv3/meson.build
--- a/libpurple/protocols/ircv3/meson.build
+++ b/libpurple/protocols/ircv3/meson.build
@@ -14,6 +14,7 @@
 IRCV3_HEADERS = [
 	'purpleircv3capabilities.h',
 	'purpleircv3connection.h',
+	'purpleircv3constants.h',
 	'purpleircv3core.h',
 	'purpleircv3message.h',
 	'purpleircv3messagehandlers.h',
diff --git a/libpurple/protocols/ircv3/purpleircv3constants.h b/libpurple/protocols/ircv3/purpleircv3constants.h
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/ircv3/purpleircv3constants.h
@@ -0,0 +1,53 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * 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, see <https://www.gnu.org/licenses/>.
+ */
+#if !defined(PURPLE_IRCV3_GLOBAL_HEADER_INSIDE) && \
+    !defined(PURPLE_IRCV3_COMPILATION)
+# error "only <libpurple/protocols/ircv3.h> may be included directly"
+#endif
+
+#ifndef PURPLE_IRCV3_CONSTANTS_H
+#define PURPLE_IRCV3_CONSTANTS_H
+
+/**
+ * PURPLE_IRCV3_MSG_TOPIC:
+ *
+ * A constant for the IRC %TOPIC message.
+ *
+ * Since: 3.0.0
+ */
+const char *PURPLE_IRCV3_MSG_TOPIC = "TOPIC";
+
+/**
+ * PURPLE_IRCV3_RPL_NOTOPIC:
+ *
+ * A constant for the IRC %NOTOPIC reply.
+ *
+ * Since: 3.0.0
+ */
+const char *PURPLE_IRCV3_RPL_NOTOPIC = "331";
+
+/**
+ * PURPLE_IRCV3_RPL_TOPIC:
+ *
+ * A constant for the IRC %TOPIC reply.
+ *
+ * Since: 3.0.0
+ */
+const char *PURPLE_IRCV3_RPL_TOPIC = "332";
+
+#endif /* PURPLE_IRCV3_CONSTANTS_H */
diff --git a/libpurple/protocols/ircv3/purpleircv3messagehandlers.h b/libpurple/protocols/ircv3/purpleircv3messagehandlers.h
--- a/libpurple/protocols/ircv3/purpleircv3messagehandlers.h
+++ b/libpurple/protocols/ircv3/purpleircv3messagehandlers.h
@@ -55,6 +55,7 @@
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_status_ignore_param0(PurpleIRCv3Message *message, GError **error, gpointer data);
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_ping(PurpleIRCv3Message *message, GError **error, gpointer data);
 G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_privmsg(PurpleIRCv3Message *message, GError **error, gpointer data);
+G_GNUC_INTERNAL gboolean purple_ircv3_message_handler_topic(PurpleIRCv3Message *message, GError **error, gpointer data);
 
 G_END_DECLS
 
diff --git a/libpurple/protocols/ircv3/purpleircv3messagehandlers.c b/libpurple/protocols/ircv3/purpleircv3messagehandlers.c
--- a/libpurple/protocols/ircv3/purpleircv3messagehandlers.c
+++ b/libpurple/protocols/ircv3/purpleircv3messagehandlers.c
@@ -21,6 +21,7 @@
 #include "purpleircv3messagehandlers.h"
 
 #include "purpleircv3connection.h"
+#include "purpleircv3constants.h"
 #include "purpleircv3core.h"
 #include "purpleircv3source.h"
 
@@ -227,3 +228,74 @@
 
 	return TRUE;
 }
+
+gboolean
+purple_ircv3_message_handler_topic(PurpleIRCv3Message *message,
+                                   GError **error,
+                                   gpointer data)
+{
+	PurpleIRCv3Connection *connection = data;
+	PurpleConversation *conversation = NULL;
+	GStrv params = NULL;
+	const char *channel = NULL;
+	const char *command = NULL;
+	const char *topic = NULL;
+	guint n_params = 0;
+
+	command = purple_ircv3_message_get_command(message);
+	params = purple_ircv3_message_get_params(message);
+	n_params = g_strv_length(params);
+
+	if(purple_strequal(command, PURPLE_IRCV3_MSG_TOPIC)) {
+		if(n_params != 2) {
+			g_set_error(error, PURPLE_IRCV3_DOMAIN, 0,
+			            "received TOPIC with %u parameters, expected 2",
+			            n_params);
+
+			return FALSE;
+		}
+
+		channel = params[0];
+		topic = params[1];
+	} else if(purple_strequal(command, PURPLE_IRCV3_RPL_NOTOPIC)) {
+		if(n_params != 3) {
+			g_set_error(error, PURPLE_IRCV3_DOMAIN, 0,
+			            "received RPL_NOTOPIC with %u parameters, expected 3",
+			            n_params);
+
+			return FALSE;
+		}
+
+		channel = params[1];
+		topic = "";
+	} else if(purple_strequal(command, PURPLE_IRCV3_RPL_TOPIC)) {
+		if(n_params != 3) {
+			g_set_error(error, PURPLE_IRCV3_DOMAIN, 0,
+			            "received RPL_TOPIC with %u parameters, expected 3",
+			            n_params);
+
+			return FALSE;
+		}
+
+		channel = params[1];
+		topic = params[2];
+	} else {
+		g_set_error(error, PURPLE_IRCV3_DOMAIN, 0, "unexpected command %s",
+		            command);
+
+		return FALSE;
+	}
+
+	conversation = purple_ircv3_connection_find_or_create_conversation(connection,
+	                                                                   channel);
+	if(!PURPLE_IS_CONVERSATION(conversation)) {
+		g_set_error(error, PURPLE_IRCV3_DOMAIN, 0,
+		            "failed to find or create channel '%s'", channel);
+
+		return FALSE;
+	}
+
+	purple_conversation_set_topic(conversation, topic);
+
+	return TRUE;
+}
diff --git a/libpurple/protocols/ircv3/purpleircv3parser.c b/libpurple/protocols/ircv3/purpleircv3parser.c
--- a/libpurple/protocols/ircv3/purpleircv3parser.c
+++ b/libpurple/protocols/ircv3/purpleircv3parser.c
@@ -442,6 +442,14 @@
 	purple_ircv3_parser_add_handler(parser, "PRIVMSG",
 	                                purple_ircv3_message_handler_privmsg);
 
+	/* Topic stuff. */
+	purple_ircv3_parser_add_handler(parser, "TOPIC",
+	                                purple_ircv3_message_handler_topic);
+	purple_ircv3_parser_add_handler(parser, "331",
+	                                purple_ircv3_message_handler_topic);
+	purple_ircv3_parser_add_handler(parser, "332",
+	                                purple_ircv3_message_handler_topic);
+
 	/* Post Registration Greetings */
 	purple_ircv3_parser_add_handlers(parser,
 	                                 purple_ircv3_message_handler_status_ignore_param0,
