--- a/libpurple/protocols/ircv3/purpleircv3capabilities.c Sun Dec 04 05:56:06 2022 -0600
+++ b/libpurple/protocols/ircv3/purpleircv3capabilities.c Mon Dec 05 05:25:58 2022 -0600
@@ -43,6 +43,8 @@
static guint signals[N_SIGNALS] = {0, };
@@ -79,6 +81,22 @@
g_signal_emit(capabilities, signals[SIG_DONE], 0);
+purple_ircv3_capabilities_add(PurpleIRCv3Capabilities *capabilities, + const char *capability) + char *equals = g_strstr_len(capability, -1, "="); + char *key = g_strndup(capability, equals - capability); + char *value = g_strdup(equals + 1); + g_hash_table_insert(capabilities->caps, key, value); + g_hash_table_insert(capabilities->caps, g_strdup(capability), NULL); /******************************************************************************
* PurpleIRCv3Capabilities Implementation
*****************************************************************************/
@@ -278,18 +296,71 @@
+ * PurpleIRCv3Capabilities::new: + * @capabilities: The instance. + * @added: The newly added capabilities. + * Emitted when the server sends the `CAP NEW` command. @added is a + * [type@GLib.Strv] of the new capabilities the server added. + * There are two approaches to how you can use this signal. You can check + * each item in @added for the values you need and parsing their values, or + * you can call #purple_ircv3_capabilities_lookup to see if the + * capabilities you're interested in have been added. + signals[SIG_NEW] = g_signal_new_class_handler( + G_OBJECT_CLASS_TYPE(klass), + * PurpleIRCv3Capabilities::del: + * @capabilities: The instance. + * @removed: The capabilities that were removed. + * Emitted when the server sends the `CAP DEL` command. @removed is a + * [type@GLib.Strv] of the capabilities that the server removed. + * There are two approaches to how you can use this signal. You can check + * each item in @removed for the values you care about, or you can call + * #purple_ircv3_capabilities_lookup to see if the capabilities you're + * interested in have been removed. + signals[SIG_DEL] = g_signal_new_class_handler( + G_OBJECT_CLASS_TYPE(klass), /******************************************************************************
*****************************************************************************/
-purple_ircv3_capabilities_handle_list(guint n_params,
+purple_ircv3_capabilities_handle_list(PurpleIRCv3Capabilities *capabilities, - G_GNUC_UNUSED GError **error,
+ G_GNUC_UNUSED GError **error) - PurpleIRCv3Capabilities *capabilities = data;
@@ -303,16 +374,7 @@
/* Add each capability to our hash table, splitting the keys and values. */
for(int i = 0; parts[i] != NULL; i++) {
- char *equals = g_strstr_len(parts[i], -1, "=");
- char *key = g_strndup(parts[i], equals - parts[i]);
- char *value = g_strdup(equals + 1);
- g_hash_table_insert(capabilities->caps, key, value);
- g_hash_table_insert(capabilities->caps, g_strdup(parts[i]), NULL);
+ purple_ircv3_capabilities_add(capabilities, parts[i]); @@ -363,6 +425,36 @@
+purple_ircv3_capabilities_handle_new(PurpleIRCv3Capabilities *capabilities, + G_GNUC_UNUSED GError **error) + for(guint i = 0; i < n_params; i++) { + purple_ircv3_capabilities_add(capabilities, params[i]); + g_signal_emit(capabilities, signals[SIG_NEW], 0, params); +purple_ircv3_capabilities_handle_del(PurpleIRCv3Capabilities *capabilities, + G_GNUC_UNUSED GError **error) + for(guint i = 0; i < n_params; i++) { + g_hash_table_remove(capabilities->caps, params[i]); + g_signal_emit(capabilities, signals[SIG_DEL], 0, params); /******************************************************************************
*****************************************************************************/
@@ -429,8 +521,8 @@
if(purple_strequal(subcommand, "LS") ||
purple_strequal(subcommand, "LIST"))
- return purple_ircv3_capabilities_handle_list(n_subparams, subparams,
+ return purple_ircv3_capabilities_handle_list(capabilities, n_subparams, } else if(purple_strequal(subcommand, "ACK")) {
return purple_ircv3_capabilities_handle_ack_nak(capabilities,
@@ -443,6 +535,12 @@
+ } else if(purple_strequal(subcommand, "NEW")) { + return purple_ircv3_capabilities_handle_new(capabilities, n_subparams, + } else if(purple_strequal(subcommand, "DEL")) { + return purple_ircv3_capabilities_handle_del(capabilities, n_subparams, g_set_error(error, PURPLE_IRCV3_DOMAIN, 0,