Replace the ui info GHashTable with a gobject.
--- a/doc/reference/libpurple/libpurple-docs.xml Fri Mar 13 22:11:34 2020 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml Fri Mar 20 08:57:57 2020 -0500
@@ -1,5 +1,5 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
@@ -66,6 +66,7 @@
<xi:include href="xml/purple-gio.xml" />
<xi:include href="xml/purpleaccountoption.xml" />
<xi:include href="xml/purpleaccountusersplit.xml" />
+ <xi:include href="xml/purpleuiinfo.xml" /> <xi:include href="xml/queuedoutputstream.xml" />
<xi:include href="xml/signals.xml" />
<xi:include href="xml/request.xml" />
@@ -93,7 +94,7 @@
- <title>Submodules</title>
+ <title>Submodules</title> --- a/finch/libfinch.c Fri Mar 13 22:11:34 2020 -0500
+++ b/finch/libfinch.c Fri Mar 20 08:57:57 2020 -0500
@@ -56,48 +56,13 @@
purple_debug_set_ui(PURPLE_DEBUG_UI(ui));
-static GHashTable *ui_info = NULL;
-static GHashTable *finch_ui_get_info(void)
+static PurpleUiInfo *ui_info = NULL;
- ui_info = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(ui_info, "name", (char*)_("Finch"));
- g_hash_table_insert(ui_info, "version", VERSION);
- g_hash_table_insert(ui_info, "website", "https://pidgin.im");
- g_hash_table_insert(ui_info, "dev_website", "https://developer.pidgin.im");
- g_hash_table_insert(ui_info, "client_type", "console");
- * This is the client key for "Finch." Please don't use this
- * key for other applications. You can not specify a client
- * key, in which case the default "libpurple" key will be used
- g_hash_table_insert(ui_info, "prpl-aim-clientkey", "ma18nmEklXMR7Cj_");
- * This is the client key for "Pidgin." It is owned by the AIM
- * account "markdoliner." Please don't use this key for other
- * applications. You can either not specify a client key, in
- * which case the default "libpurple" key will be used, or you
- * can try to register your own at the AIM or ICQ web sites
- * (although this functionality was removed at some point, it's
- * possible it has been re-added). AOL's old key management
- * page is http://developer.aim.com/manageKeys.jsp
- * We used to have a Finch-specific devId/clientkey
- * (ma19sqWV9ymU6UYc), but it stopped working, so we switched
- g_hash_table_insert(ui_info, "prpl-icq-clientkey", "ma1cSASNCKFtrdv9");
- * This is the distid for Finch, given to us by AOL. Please
- * don't use this for other applications. You can just not
- * specify a distid and libpurple will use a default.
- g_hash_table_insert(ui_info, "prpl-aim-distid", GINT_TO_POINTER(1718));
- g_hash_table_insert(ui_info, "prpl-icq-distid", GINT_TO_POINTER(1552));
+ if(!PURPLE_IS_UI_INFO(ui_info)) { + ui_info = purple_ui_info_new(_("Finch"), VERSION, "https://pidgin.im", + "https://developer.pidgin.im", "console"); @@ -107,8 +72,7 @@
- g_hash_table_destroy(ui_info);
+ g_clear_object(&ui_info); static PurpleCoreUiOps core_ops =
@@ -118,12 +82,6 @@
--- a/libpurple/core.c Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/core.c Fri Mar 20 08:57:57 2020 -0500
@@ -61,13 +61,13 @@
purple_core_print_version(void)
- GHashTable *ui_info = purple_core_get_ui_info();
+ PurpleUiInfo *ui_info = purple_core_get_ui_info(); gchar *ui_full_name = NULL;
- ui_name = ui_info ? g_hash_table_lookup(ui_info, "name") : NULL;
- ui_version = ui_info ? g_hash_table_lookup(ui_info, "version") : NULL;
+ ui_name = ui_info ? purple_ui_info_get_name(ui_info) : NULL; + ui_version = ui_info ? purple_ui_info_get_version(ui_info) : NULL; @@ -83,6 +83,7 @@
purple_core_get_version());
+ g_object_unref(G_OBJECT(ui_info)); @@ -333,7 +334,7 @@
-GHashTable* purple_core_get_ui_info() {
+PurpleUiInfo* purple_core_get_ui_info() { PurpleCoreUiOps *ops = purple_core_get_ui_ops();
if(NULL == ops || NULL == ops->get_ui_info)
--- a/libpurple/core.h Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/core.h Fri Mar 20 08:57:57 2020 -0500
@@ -32,6 +32,8 @@
+#include <libpurple/purpleuiinfo.h> #define PURPLE_TYPE_CORE_UI_OPS (purple_core_ui_ops_get_type())
typedef struct PurpleCore PurpleCore;
@@ -66,13 +68,10 @@
- GHashTable* (*get_ui_info)(void);
+ PurpleUiInfo *(*get_ui_info)(void); - void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
@@ -175,52 +174,20 @@
* purple_core_get_ui_info:
- * Returns a hash table containing various information about the UI. The
- * following well-known entries may be in the table (along with any others the
- * UI might choose to include):
+ * Returns a #PurpleUiInfo that contains information about the user interface. - * <informaltable frame='none'>
- * <tgroup cols='2'><tbody>
- * <entry><literal>name</literal></entry>
- * <entry>the user-readable name for the UI.</entry>
- * <entry><literal>version</literal></entry>
- * <entry>a user-readable description of the current version of the UI.</entry>
- * <entry><literal>website</literal></entry>
- * <entry>the UI's website, such as https://pidgin.im.</entry>
- * <entry><literal>dev_website</literal></entry>
- * <entry>the UI's development/support website, such as
- * https://developer.pidgin.im.</entry>
- * <entry><literal>client_type</literal></entry>
- * <entry>the type of UI. Possible values include 'pc', 'console', 'phone',
- * 'handheld', 'web', and 'bot'. These values are compared
- * programmatically and should not be localized.</entry>
- * Returns: (transfer none): A GHashTable with strings for keys and values.
- * This hash table should not be modified.
+ * Returns: (transfer full): A #PurpleUiInfo instance. -GHashTable* purple_core_get_ui_info(void);
+PurpleUiInfo* purple_core_get_ui_info(void); * purple_core_migrate_to_xdg_base_dirs:
- * Migrates from legacy directory for libpurple to location following
+ * Migrates from legacy directory for libpurple to location following * XDG base dir spec. https://developer.pidgin.im/ticket/10029
* NOTE This is not finished yet. Need to decide where other profile files
* should be moved. Search for usages of purple_user_dir().
* Returns: TRUE if migrated successfully, FALSE otherwise. On failure,
* the application must display an error to the user and then exit.
--- a/libpurple/meson.build Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/meson.build Fri Mar 20 08:57:57 2020 -0500
@@ -48,6 +48,7 @@
'purpleaccountusersplit.c',
@@ -124,6 +125,7 @@
'purpleaccountusersplit.h',
--- a/libpurple/plugins/keyrings/kwallet/purplekwallet.cpp Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/plugins/keyrings/kwallet/purplekwallet.cpp Fri Mar 20 08:57:57 2020 -0500
@@ -400,14 +400,18 @@
static const char *kwallet_get_ui_name(void)
+ PurpleUiInfo *ui_info = NULL; const char *ui_name = NULL;
ui_info = purple_core_get_ui_info();
- ui_name = (const char*)g_hash_table_lookup(ui_info, "name");
+ if(PURPLE_IS_UI_INFO(ui_info)) { + ui_name = purple_ui_info_get_name(ui_info); + g_object_unref(G_OBJECT(ui_info)); ui_name = KWALLET_APP_NAME;
--- a/libpurple/protocols/jabber/bosh.c Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/protocols/jabber/bosh.c Fri Mar 20 08:57:57 2020 -0500
@@ -64,21 +64,26 @@
- GHashTable *ui_info = purple_core_get_ui_info();
+ PurpleUiInfo *ui_info = purple_core_get_ui_info(); const gchar *ui_name = NULL;
const gchar *ui_version = NULL;
- ui_name = g_hash_table_lookup(ui_info, "name");
- ui_version = g_hash_table_lookup(ui_info, "version");
+ ui_name = purple_ui_info_get_name(ui_info); + ui_version = purple_ui_info_get_version(ui_info);
jabber_bosh_useragent = g_strdup_printf(
"%s%s%s (libpurple " VERSION ")", ui_name,
ui_version ? " " : "", ui_version ? ui_version : "");
jabber_bosh_useragent = g_strdup("libpurple " VERSION);
+ g_object_unref(G_OBJECT(ui_info)); void jabber_bosh_uninit(void)
--- a/libpurple/protocols/jabber/iq.c Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/protocols/jabber/iq.c Fri Mar 20 08:57:57 2020 -0500
@@ -228,7 +228,7 @@
if(type == JABBER_IQ_GET) {
const char *ui_name = NULL, *ui_version = NULL;
iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:version");
@@ -240,9 +240,9 @@
ui_info = purple_core_get_ui_info();
- ui_name = g_hash_table_lookup(ui_info, "name");
- ui_version = g_hash_table_lookup(ui_info, "version");
+ if(PURPLE_IS_UI_INFO(ui_info)) { + ui_name = purple_ui_info_get_name(ui_info); + ui_version = purple_ui_info_get_version(ui_info); if(NULL != ui_name && NULL != ui_version) {
@@ -256,6 +256,10 @@
+ if(PURPLE_IS_UI_INFO(ui_info)) { + g_object_unref(G_OBJECT(ui_info)); --- a/libpurple/protocols/jabber/jabber.c Fri Mar 13 22:11:34 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.c Fri Mar 20 08:57:57 2020 -0500
@@ -3815,7 +3815,7 @@
- GHashTable *ui_info = purple_core_get_ui_info();
+ PurpleUiInfo *ui_info = purple_core_get_ui_info(); const gchar *type = "pc"; /* default client type, if unknown or
@@ -3853,7 +3853,7 @@
jabber_cmds = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, cmds_free_func);
- ui_type = ui_info ? g_hash_table_lookup(ui_info, "client_type") : NULL;
+ ui_type = ui_info ? purple_ui_info_get_client_type(ui_info) : NULL; if (purple_strequal(ui_type, "pc") ||
purple_strequal(ui_type, "console") ||
@@ -3866,7 +3866,7 @@
- ui_name = g_hash_table_lookup(ui_info, "name");
+ ui_name = purple_ui_info_get_name(ui_info); @@ -3930,6 +3930,8 @@
+ g_object_unref(G_OBJECT(ui_info)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleuiinfo.c Fri Mar 20 08:57:57 2020 -0500
@@ -0,0 +1,281 @@
+ * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +#include "purpleuiinfo.h" + gchar *support_website; +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; +/****************************************************************************** + *****************************************************************************/ +purple_ui_info_set_name(PurpleUiInfo *info, const gchar *name) { + info->name = g_strdup(name); +purple_ui_info_set_version(PurpleUiInfo *info, const gchar *version) { + info->version = g_strdup(version); +purple_ui_info_set_website(PurpleUiInfo *info, const gchar *website) { + info->website = g_strdup(website); +purple_ui_info_set_support_website(PurpleUiInfo *info, + const gchar *support_website) + g_free(info->support_website); + info->support_website = g_strdup(support_website); +purple_ui_info_set_client_type(PurpleUiInfo *info, const gchar *client_type) { + g_free(info->client_type); + info->client_type = g_strdup(client_type); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_TYPE(PurpleUiInfo, purple_ui_info, G_TYPE_OBJECT); +purple_ui_info_get_property(GObject *obj, guint param_id, GValue *value, + PurpleUiInfo *info = PURPLE_UI_INFO(obj); + g_value_set_string(value, purple_ui_info_get_name(info)); + g_value_set_string(value, purple_ui_info_get_version(info)); + g_value_set_string(value, purple_ui_info_get_website(info)); + case PROP_SUPPORT_WEBSITE: + g_value_set_string(value, purple_ui_info_get_support_website(info)); + g_value_set_string(value, purple_ui_info_get_client_type(info)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_ui_info_set_property(GObject *obj, guint param_id, const GValue *value, + PurpleUiInfo *info = PURPLE_UI_INFO(obj); + purple_ui_info_set_name(info, g_value_get_string(value)); + purple_ui_info_set_version(info, g_value_get_string(value)); + purple_ui_info_set_website(info, g_value_get_string(value)); + case PROP_SUPPORT_WEBSITE: + purple_ui_info_set_support_website(info, + g_value_get_string(value)); + purple_ui_info_set_client_type(info, g_value_get_string(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_ui_info_init(PurpleUiInfo *info) { +purple_ui_info_finalize(GObject *obj) { + PurpleUiInfo *info = PURPLE_UI_INFO(obj); + g_clear_pointer(&info->name, g_free); + g_clear_pointer(&info->version, g_free); + g_clear_pointer(&info->website, g_free); + g_clear_pointer(&info->support_website, g_free); + g_clear_pointer(&info->client_type, g_free); + G_OBJECT_CLASS(purple_ui_info_parent_class)->finalize(obj); +purple_ui_info_class_init(PurpleUiInfoClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = purple_ui_info_get_property; + obj_class->set_property = purple_ui_info_set_property; + obj_class->finalize = purple_ui_info_finalize; + * The name of the user interface. + properties[PROP_NAME] = + g_param_spec_string("name", "name", "The name of the user interface", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + * PurpleUiInfo::version: + * The name of the user interface. + properties[PROP_VERSION] = + g_param_spec_string("version", "version", + "The version of the user interface", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + * PurpleUiInfo::website: + * The website of the user interface. + properties[PROP_WEBSITE] = + g_param_spec_string("website", "website", + "The website of the user interface", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + * PurpleUiInfo::support-website: + * The support website of the user interface. + properties[PROP_SUPPORT_WEBSITE] = + g_param_spec_string("support-website", "support-website", + "The support website of the user interface", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + * PurpleUiInfo::client-type: + * The client type of the user interface. + properties[PROP_CLIENT_TYPE] = + g_param_spec_string("client-type", "client-type", + "The client type of the user interface", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +/****************************************************************************** + *****************************************************************************/ +purple_ui_info_new(const gchar *name, const gchar *version, + const gchar *website, const gchar *support_website, + const gchar *client_type) + return g_object_new(PURPLE_TYPE_UI_INFO, + "support-website", support_website, + "client-type", client_type, +purple_ui_info_get_name(PurpleUiInfo *info) { + g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL); +purple_ui_info_get_version(PurpleUiInfo *info) { + g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL); +purple_ui_info_get_website(PurpleUiInfo *info) { + g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL); +purple_ui_info_get_support_website(PurpleUiInfo *info) { + g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL); + return info->support_website; +purple_ui_info_get_client_type(PurpleUiInfo *info) { + g_return_val_if_fail(PURPLE_IS_UI_INFO(info), NULL); + return info->client_type; --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purpleuiinfo.h Fri Mar 20 08:57:57 2020 -0500
@@ -0,0 +1,126 @@
+ * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA +#ifndef PURPLE_UI_INFO_H +#define PURPLE_UI_INFO_H + * @section_id: libpurple-ui-info + * @short_description: <filename>purpleuiinfo.h</filename> + * @title: A simple class that contains information about a user interface. +#include <glib-object.h> +#define PURPLE_TYPE_UI_INFO (purple_ui_info_get_type()) +G_DECLARE_FINAL_TYPE(PurpleUiInfo, purple_ui_info, PURPLE, UI_INFO, GObject) + * @version: The version. + * @website: The website. + * @support_website: The support website. + * @client_type: The client type. + * Creates a new #PurpleUiInfo with the given values. If you only want to set + * a few of these, you should use g_object_new() directly. + * Returns: (transfer full): The newly created #PurpleUiInfo instance. +PurpleUiInfo *purple_ui_info_new(const gchar *name, + const gchar *support_website, + const gchar *client_type); + * purple_ui_info_get_name: + * @info: The #PurpleUiInfo instance. + * Gets the name from @info. + * Returns: The name from @info. +const gchar *purple_ui_info_get_name(PurpleUiInfo *info); + * purple_ui_info_get_version: + * @info: The #PurpleUiInfo instance. + * Gets the version from @info. + * Returns: The version from @info. +const gchar *purple_ui_info_get_version(PurpleUiInfo *info); + * purple_ui_info_get_website: + * @info: The #PurpleUiInfo instance. + * Gets the website from @info. + * Returns: The website for @info. +const gchar *purple_ui_info_get_website(PurpleUiInfo *info); + * purple_ui_info_get_support_website: + * @info: The #PurpleUiInfo instance. + * Gets the support website from @info. + * Returns: The support website from @info. +const gchar *purple_ui_info_get_support_website(PurpleUiInfo *info); + * purple_ui_info_get_client_type: + * @info: The #PurpleUiInfo instance. + * Gets the client type from @info. For example: 'bot', 'console', 'mobile', + * Returns: The client type of @info. +const gchar *purple_ui_info_get_client_type(PurpleUiInfo *info); +#endif /* PURPLE_UI_INFO_H */ --- a/pidgin/libpidgin.c Fri Mar 13 22:11:34 2020 -0500
+++ b/pidgin/libpidgin.c Fri Mar 20 08:57:57 2020 -0500
@@ -248,7 +248,7 @@
-static GHashTable *ui_info = NULL;
+static PurpleUiInfo *ui_info = NULL; @@ -269,46 +269,17 @@
purple_debug_set_ui(NULL);
- g_hash_table_destroy(ui_info);
+ g_clear_object(&ui_info); g_application_quit(g_application_get_default());
-static GHashTable *pidgin_ui_get_info(void)
+static PurpleUiInfo *pidgin_ui_get_info(void) - ui_info = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(ui_info, "name", (char*)PIDGIN_NAME);
- g_hash_table_insert(ui_info, "version", VERSION);
- g_hash_table_insert(ui_info, "website", "https://pidgin.im");
- g_hash_table_insert(ui_info, "dev_website", "https://developer.pidgin.im");
- g_hash_table_insert(ui_info, "client_type", "pc");
- * prpl-aim-clientkey is a DevID (or "client key") for Pidgin, given to
- * us by AOL in September 2016. prpl-icq-clientkey is also a client key
- * for Pidgin, owned by the AIM account "markdoliner." Please don't use
- * either for other applications. Instead, you can either not specify a
- * client key, in which case the default "libpurple" key will be used,
- * or you can try to register your own at the AIM or ICQ web sites
- * (although this functionality was removed at some point, it's possible
- * it has been re-added).
- g_hash_table_insert(ui_info, "prpl-aim-clientkey", "do1UCeb5gNqxB1S1");
- g_hash_table_insert(ui_info, "prpl-icq-clientkey", "ma1cSASNCKFtrdv9");
- * prpl-aim-distid is a distID for Pidgin, given to us by AOL in
- * September 2016. prpl-icq-distid is also a distID for Pidgin, given
- * to us by AOL. Please don't use either for other applications.
- * Instead, you can just not specify a distID and libpurple will use a
- g_hash_table_insert(ui_info, "prpl-aim-distid", GINT_TO_POINTER(1715));
- g_hash_table_insert(ui_info, "prpl-icq-distid", GINT_TO_POINTER(1550));
+ ui_info = purple_ui_info_new(PIDGIN_NAME, VERSION, "https://pidgin.im", + "https://developer.pidgin.im", "pc"); @@ -321,10 +292,6 @@