Modernize PurpleProtocol
* Migrate PurpleProtocol to the `G_DECLARE_DERIVABLE_TYPE` and `G_DEFINE_TYPE` macros.
* Rename `purple_protocol_class_*` to `purple_protocol_*`.
* Move the class properties to instance properties and add accessors as necessary.
Testing Done:
Ran locally and connected with bonjour, facebook, irc, and xmpp. Verified that the other prpls are loading and visible in the account manager.
Bugs closed: PIDGIN-17492
Reviewed at https://reviews.imfreedom.org/r/552/
--- a/finch/gntaccount.c Mon Mar 08 20:19:07 2021 -0600
+++ b/finch/gntaccount.c Mon Mar 08 23:22:02 2021 -0600
@@ -117,8 +117,9 @@
- for (iter = purple_protocol_get_user_splits(protocol), entries = dialog->split_entries;
+ GList *iter, *entries, *splits; + splits = purple_protocol_get_user_splits(protocol); + for (iter = splits, entries = dialog->split_entries; iter && entries; iter = iter->next, entries = entries->next)
PurpleAccountUserSplit *split = iter->data;
@@ -131,6 +132,8 @@
purple_account_user_split_get_separator(split),
+ g_list_free_full(splits, + (GDestroyNotify)purple_account_user_split_destroy); if (dialog->account == NULL)
@@ -199,9 +202,10 @@
+ GList *iter, *entries, *opts; - for (iter = purple_protocol_get_account_options(protocol), entries = dialog->protocol_entries;
+ opts = purple_protocol_get_account_options(protocol); + for (iter = opts, entries = dialog->protocol_entries; iter && entries; iter = iter->next, entries = entries->next)
PurpleAccountOption *option = iter->data;
@@ -237,6 +241,7 @@
+ g_list_free_full(opts, (GDestroyNotify)purple_account_option_destroy); @@ -279,7 +284,7 @@
PurpleProtocol *protocol;
+ GList *iter, *entries, *splits; @@ -302,7 +307,8 @@
username = dialog->account ? g_strdup(purple_account_get_username(dialog->account)) : NULL;
- for (iter = purple_protocol_get_user_splits(protocol); iter; iter = iter->next)
+ splits = purple_protocol_get_user_splits(protocol); + for (iter = splits; iter; iter = iter->next) PurpleAccountUserSplit *split = iter->data;
@@ -323,7 +329,7 @@
- for (iter = g_list_last(purple_protocol_get_user_splits(protocol)), entries = g_list_last(dialog->split_entries);
+ for (iter = g_list_last(splits), entries = g_list_last(dialog->split_entries); iter && entries; iter = iter->prev, entries = entries->prev)
GntWidget *entry = entries->data;
@@ -352,6 +358,8 @@
gnt_entry_set_text(GNT_ENTRY(entry), value);
+ g_list_free_full(splits, (GDestroyNotify)purple_account_user_split_destroy); gnt_entry_set_text(GNT_ENTRY(dialog->username), username);
@@ -362,7 +370,7 @@
add_account_options(AccountEditDialog *dialog)
PurpleProtocol *protocol;
@@ -390,7 +398,8 @@
account = dialog->account;
- for (iter = purple_protocol_get_account_options(protocol); iter; iter = iter->next)
+ opts = purple_protocol_get_account_options(protocol); + for (iter = opts; iter; iter = iter->next) PurpleAccountOption *option = iter->data;
PurplePrefType type = purple_account_option_get_pref_type(option);
@@ -477,6 +486,7 @@
+ g_list_free_full(opts, (GDestroyNotify)purple_account_option_destroy); /* Show the registration checkbox only in a new account dialog,
* and when the selected protocol has the support for it. */
--- a/libpurple/account.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/account.c Mon Mar 08 23:22:02 2021 -0600
@@ -1015,7 +1015,7 @@
purple_account_set_status_types(account,
- purple_protocol_class_status_types(protocol, account));
+ purple_protocol_get_status_types(protocol, account)); priv->presence = PURPLE_PRESENCE(purple_account_presence_new(account));
--- a/libpurple/buddyicon.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/buddyicon.c Mon Mar 08 23:22:02 2021 -0600
@@ -1168,6 +1168,15 @@
+purple_buddy_icon_spec_free(PurpleBuddyIconSpec *spec) { static PurpleBuddyIconSpec *
purple_buddy_icon_spec_copy(PurpleBuddyIconSpec *icon_spec)
@@ -1219,7 +1228,7 @@
type = g_boxed_type_register_static("PurpleBuddyIconSpec",
(GBoxedCopyFunc)purple_buddy_icon_spec_copy,
- (GBoxedFreeFunc)g_free);
+ (GBoxedFreeFunc)purple_buddy_icon_spec_free); --- a/libpurple/buddyicon.h Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/buddyicon.h Mon Mar 08 23:22:02 2021 -0600
@@ -521,6 +521,16 @@
PurpleBuddyIconScaleFlags scale_rules);
+ * purple_buddy_icon_spec_free: + * @spec: The #PurpleBuddyIconSpec instance. +void purple_buddy_icon_spec_free(PurpleBuddyIconSpec *spec); * purple_buddy_icon_spec_get_scaled_size:
* @spec: The buddy icon spec.
* @width: (inout): On input, the suggested width. On output, the width
--- a/libpurple/connection.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/connection.c Mon Mar 08 23:22:02 2021 -0600
@@ -886,7 +886,7 @@
update_keepalive(gc, FALSE);
- purple_protocol_class_close(priv->protocol, gc);
+ purple_protocol_close(priv->protocol, gc); /* Clear out the proto data that was freed in the protocol's close method */
buddies = purple_blist_find_buddies(account, NULL);
@@ -1048,7 +1048,7 @@
purple_debug_info("connection", "Connecting. gc = %p\n", gc);
purple_signal_emit(purple_accounts_get_handle(), "account-connecting", account);
- purple_protocol_class_login(protocol, account);
+ purple_protocol_login(protocol, account); --- a/libpurple/log.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/log.c Mon Mar 08 23:22:02 2021 -0600
@@ -287,7 +287,7 @@
- protocol_name = purple_protocol_class_list_icon(protocol, account, NULL);
+ protocol_name = purple_protocol_get_list_icon(protocol, account, NULL); acct_name = g_strdup(purple_escape_filename(purple_normalize(account,
purple_account_get_username(account))));
@@ -996,7 +996,7 @@
- if (purple_strequal(protocol_unescaped, purple_protocol_class_list_icon(protocol, (PurpleAccount *)account_iter->data, NULL)))
+ if (purple_strequal(protocol_unescaped, purple_protocol_get_list_icon(protocol, (PurpleAccount *)account_iter->data, NULL))) accounts = g_list_prepend(accounts, account_iter->data);
g_free(protocol_unescaped);
@@ -1182,7 +1182,7 @@
- const char *proto = purple_protocol_class_list_icon(protocol, log->account, NULL);
+ const char *proto = purple_protocol_get_list_icon(protocol, log->account, NULL); purple_log_common_writer(log, ".html");
@@ -1344,7 +1344,7 @@
* creating a new file there would result in empty files in the case
* that you open a convo with someone, but don't say anything.
- const char *proto = purple_protocol_class_list_icon(protocol, log->account, NULL);
+ const char *proto = purple_protocol_get_list_icon(protocol, log->account, NULL); purple_log_common_writer(log, ".txt");
--- a/libpurple/plugins/log_reader.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/plugins/log_reader.c Mon Mar 08 23:22:02 2021 -0600
@@ -79,7 +79,7 @@
- protocol_name = g_ascii_strup(purple_protocol_class_list_icon(protocol, account, NULL), -1);
+ protocol_name = g_ascii_strup(purple_protocol_get_list_icon(protocol, account, NULL), -1); temp = g_strdup_printf("%s.%s", protocol_name, purple_account_get_username(account));
path = g_build_filename(logdir, temp, sn, NULL);
@@ -1090,7 +1090,7 @@
- protocol_name = g_ascii_strup(purple_protocol_class_list_icon(protocol, account, NULL), -1);
+ protocol_name = g_ascii_strup(purple_protocol_get_list_icon(protocol, account, NULL), -1); buddy_name = purple_normalize(account, sn);
--- a/libpurple/protocol.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocol.c Mon Mar 08 23:22:02 2021 -0600
@@ -1,5 +1,6 @@
+ * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> * 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
@@ -16,109 +17,150 @@
* 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
+ * along with this program; if not, see <https://www.gnu.org/licenses/>. -static GObjectClass *parent_class;
-/**************************************************************************
- **************************************************************************/
-purple_protocol_get_id(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+ PurpleProtocolOptions options; +} PurpleProtocolPrivate; +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleProtocol, purple_protocol,
-purple_protocol_get_name(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+/****************************************************************************** + *****************************************************************************/ +purple_protocol_set_id(PurpleProtocol *protocol, const gchar *id) { + PurpleProtocolPrivate *priv = NULL;
+ priv = purple_protocol_get_instance_private(protocol); + priv->id = g_strdup(id); + g_object_notify_by_pspec(G_OBJECT(protocol), properties[PROP_ID]);
-purple_protocol_get_options(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), 0);
- return protocol->options;
-purple_protocol_get_user_splits(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
- return protocol->user_splits;
+purple_protocol_set_name(PurpleProtocol *protocol, const gchar *name) { + PurpleProtocolPrivate *priv = NULL;
-purple_protocol_get_account_options(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
- return protocol->account_options;
+ priv = purple_protocol_get_instance_private(protocol); + priv->name = g_strdup(name);
-purple_protocol_get_icon_spec(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
- return protocol->icon_spec;
-purple_protocol_get_whiteboard_ops(const PurpleProtocol *protocol)
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
- return protocol->whiteboard_ops;
+ g_object_notify_by_pspec(G_OBJECT(protocol), properties[PROP_NAME]); -icon_spec_free(PurpleProtocol *protocol)
+purple_protocol_set_options(PurpleProtocol *protocol, + PurpleProtocolOptions options) - g_return_if_fail(PURPLE_IS_PROTOCOL(protocol));
+ PurpleProtocolPrivate *priv = NULL; - g_free(protocol->icon_spec);
- protocol->icon_spec = NULL;
+ priv = purple_protocol_get_instance_private(protocol); + priv->options = options; + g_object_notify_by_pspec(G_OBJECT(protocol), properties[PROP_OPTIONS]); -/**************************************************************************
- **************************************************************************/
+/****************************************************************************** + * GObject Implementation + *****************************************************************************/ -purple_protocol_init(GTypeInstance *instance, gpointer klass)
+purple_protocol_get_property(GObject *obj, guint param_id, GValue *value, + PurpleProtocol *protocol = PURPLE_PROTOCOL(obj); + g_value_set_string(value, purple_protocol_get_id(protocol)); + g_value_set_string(value, purple_protocol_get_name(protocol)); + g_value_set_flags(value, purple_protocol_get_options(protocol)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); -purple_protocol_finalize(GObject *object)
+purple_protocol_set_property(GObject *obj, guint param_id, const GValue *value, + PurpleProtocol *protocol = PURPLE_PROTOCOL(obj); + purple_protocol_set_id(protocol, g_value_get_string(value)); + purple_protocol_set_name(protocol, g_value_get_string(value)); + purple_protocol_set_options(protocol, g_value_get_flags(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_protocol_init(PurpleProtocol *protocol) { +purple_protocol_finalize(GObject *object) { PurpleProtocol *protocol = PURPLE_PROTOCOL(object);
+ PurpleProtocolPrivate *priv = NULL; + priv = purple_protocol_get_instance_private(protocol); + g_clear_pointer(&priv->id, g_free); + g_clear_pointer(&priv->name, g_free); + /* I'm not sure that we can finalize a protocol plugin if an account is + * still using it.. Right now accounts don't ref protocols, but maybe accounts = purple_accounts_get_all_active();
for (l = accounts; l != NULL; l = l->next) {
PurpleAccount *account = PURPLE_ACCOUNT(l->data);
if (purple_account_is_disconnected(account))
- if (purple_strequal(protocol->id,
- purple_account_get_protocol_id(account)))
+ if (purple_strequal(priv->id, purple_account_get_protocol_id(account))) purple_account_disconnect(account);
+ /* these seem to be fallbacks if the subclass protocol doesn't do it's own + * clean up? I kind of want to delete them... - gk 2021-03-03 purple_request_close_with_handle(protocol);
purple_notify_close_with_handle(protocol);
@@ -127,85 +169,201 @@
purple_prefs_disconnect_by_handle(protocol);
- g_list_free_full(protocol->user_splits, (GDestroyNotify)purple_account_user_split_destroy);
- g_list_free_full(protocol->account_options, (GDestroyNotify)purple_account_option_destroy);
- icon_spec_free(protocol);
- parent_class->finalize(object);
+ G_OBJECT_CLASS(purple_protocol_parent_class)->finalize(object); -purple_protocol_class_init(PurpleProtocolClass *klass)
+purple_protocol_class_init(PurpleProtocolClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- parent_class = g_type_class_peek_parent(klass);
+ obj_class->get_property = purple_protocol_get_property; + obj_class->set_property = purple_protocol_set_property; + obj_class->finalize = purple_protocol_finalize; + * The identifier for the protocol. + properties[PROP_ID] = g_param_spec_string( + "The identifier for the protocol", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + * PurpleProtocol::name: + * The name to show in user interface for the protocol. + properties[PROP_NAME] = g_param_spec_string( + "The name of the protocol to show in the user interface", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - obj_class->finalize = purple_protocol_finalize;
+ * PurpleProtocol::options: + * The #PurpleProtocolOptions for the protocol. + properties[PROP_OPTIONS] = g_param_spec_flags( + "The options for the protocol", + PURPLE_TYPE_PROTOCOL_OPTIONS, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +/****************************************************************************** + *****************************************************************************/ +purple_protocol_get_id(PurpleProtocol *protocol) { + PurpleProtocolPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); + priv = purple_protocol_get_instance_private(protocol);
-purple_protocol_get_type(void)
+purple_protocol_get_name(PurpleProtocol *protocol) { + PurpleProtocolPrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); + priv = purple_protocol_get_instance_private(protocol); +purple_protocol_get_options(PurpleProtocol *protocol) { + PurpleProtocolPrivate *priv = NULL; - if (G_UNLIKELY(type == 0)) {
- static const GTypeInfo info = {
- .class_size = sizeof(PurpleProtocolClass),
- .class_init = (GClassInitFunc)purple_protocol_class_init,
- .instance_size = sizeof(PurpleProtocol),
- .instance_init = (GInstanceInitFunc)purple_protocol_init,
+ g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), 0); + priv = purple_protocol_get_instance_private(protocol); - type = g_type_register_static(G_TYPE_OBJECT, "PurpleProtocol",
- &info, G_TYPE_FLAG_ABSTRACT);
+purple_protocol_get_user_splits(PurpleProtocol *protocol) { + PurpleProtocolClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); + klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->get_user_splits != NULL) { + return klass->get_user_splits(protocol);
-/**************************************************************************
- **************************************************************************/
-#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
- PurpleProtocolClass *klass = PURPLE_PROTOCOL_GET_CLASS(protocol); \
- g_return_if_fail(klass != NULL); \
- klass->funcname(__VA_ARGS__);
+purple_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleProtocolClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); + klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->get_account_options != NULL) { + return klass->get_account_options(protocol); +purple_protocol_get_icon_spec(PurpleProtocol *protocol) { + PurpleProtocolClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); -#define DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol,defaultreturn,funcname,...) \
- PurpleProtocolClass *klass = PURPLE_PROTOCOL_GET_CLASS(protocol); \
- g_return_val_if_fail(klass != NULL, defaultreturn); \
- return klass->funcname(__VA_ARGS__); \
+ klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->get_buddy_icon_spec != NULL) { + return klass->get_buddy_icon_spec(protocol);
-purple_protocol_class_login(PurpleProtocol *protocol, PurpleAccount *account)
- DEFINE_PROTOCOL_FUNC(protocol, login, account);
+purple_protocol_get_whiteboard_ops(PurpleProtocol *protocol) { + PurpleProtocolClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); + klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->get_whiteboard_ops != NULL) { + return klass->get_whiteboard_ops(protocol); -purple_protocol_class_close(PurpleProtocol *protocol, PurpleConnection *gc)
- DEFINE_PROTOCOL_FUNC(protocol, close, gc);
+purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account) { + PurpleProtocolClass *klass = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL(protocol)); + g_return_if_fail(PURPLE_IS_ACCOUNT(account)); + klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->login != NULL) { +purple_protocol_close(PurpleProtocol *protocol, PurpleConnection *gc) { + PurpleProtocolClass *klass = NULL; + g_return_if_fail(PURPLE_IS_PROTOCOL(protocol)); + g_return_if_fail(PURPLE_IS_CONNECTION(gc)); + klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->close != NULL) { -purple_protocol_class_status_types(PurpleProtocol *protocol,
- PurpleAccount *account)
+purple_protocol_get_status_types(PurpleProtocol *protocol, + PurpleAccount *account) - DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, status_types, account);
+ PurpleProtocolClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); + g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); + klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->status_types != NULL) { + return klass->status_types(account);
-purple_protocol_class_list_icon(PurpleProtocol *protocol,
- PurpleAccount *account, PurpleBuddy *buddy)
+purple_protocol_get_list_icon(PurpleProtocol *protocol, PurpleAccount *account, - DEFINE_PROTOCOL_FUNC_WITH_RETURN(protocol, NULL, list_icon, account, buddy);
+ PurpleProtocolClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL); -#undef DEFINE_PROTOCOL_FUNC_WITH_RETURN
-#undef DEFINE_PROTOCOL_FUNC
+ klass = PURPLE_PROTOCOL_GET_CLASS(protocol); + if(klass != NULL && klass->list_icon != NULL) { + return klass->list_icon(account, buddy); --- a/libpurple/protocol.h Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocol.h Mon Mar 08 23:22:02 2021 -0600
@@ -27,6 +27,9 @@
#ifndef PURPLE_PROTOCOL_H
#define PURPLE_PROTOCOL_H
+#include <glib-object.h> * @section_id: libpurple-protocol
@@ -36,15 +39,9 @@
* #PurpleProtocol is the base type for all protocols in libpurple.
-#define PURPLE_TYPE_PROTOCOL (purple_protocol_get_type())
-#define PURPLE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_PROTOCOL, PurpleProtocol))
-#define PURPLE_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_PROTOCOL, PurpleProtocolClass))
-#define PURPLE_IS_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_PROTOCOL))
-#define PURPLE_IS_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_PROTOCOL))
-#define PURPLE_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_PROTOCOL, PurpleProtocolClass))
-typedef struct _PurpleProtocol PurpleProtocol;
-typedef struct _PurpleProtocolClass PurpleProtocolClass;
+#define PURPLE_TYPE_PROTOCOL (purple_protocol_get_type()) +G_DECLARE_DERIVABLE_TYPE(PurpleProtocol, purple_protocol, PURPLE, PROTOCOL, @@ -67,75 +64,51 @@
- * @name: Translated name of the protocol
- * @options: Protocol options
- * @user_splits: A GList of PurpleAccountUserSplit
- * @account_options: A GList of PurpleAccountOption
- * @icon_spec: The icon spec.
- * @whiteboard_ops: Whiteboard operations
- * Represents an instance of a protocol registered with the protocols
- * subsystem. Protocols must initialize the members to appropriate values.
+ * Represents an instance of a protocol registered with #PurpleProtocolManager.
- PurpleProtocolOptions options;
- GList *account_options;
- PurpleBuddyIconSpec *icon_spec;
- PurpleWhiteboardOps *whiteboard_ops;
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
- * @login: Log in to the server.
- * @close: Close connection with the server.
+ * @get_user_splits: Returns a list of all #PurpleAccountUserSplit's that the + * @get_account_options: Returns a list of all #PurpleAccountOption's for the + * @get_buddy_icon_spec: Returns a #PurpleBuddyIconSpec that should be used. + * @get_whiteboard_ops: Return the #PurpleWhiteboardOps that should be used. + * @login: Logs into the server. + * @close: Close sconnection with the server. * @status_types: Returns a list of #PurpleStatusType which exist for this
* account; and must add at least the offline and online states.
- * @list_icon: Returns the base icon name for the given buddy and account. If
- * buddy is %NULL and the account is non-%NULL, it will return
- * the name to use for the account's icon. If both are %NULL, it
- * will return the name to use for the protocol's icon.
+ * @list_icon: Returns the base icon name for the given buddy and account. If + * buddy is %NULL and the account is non-%NULL, it will return the + * name to use for the account's icon. If both are %NULL, it will + * return the name to use for the protocol's icon. * The base class for all protocols.
* All protocol types must implement the methods in this class.
-/* If adding new methods to this class, ensure you add checks for them in
- purple_protocols_add().
-struct _PurpleProtocolClass
+struct _PurpleProtocolClass { GObjectClass parent_class;
+ GList *(*get_user_splits)(PurpleProtocol *protocol); + GList *(*get_account_options)(PurpleProtocol *protocol); + PurpleBuddyIconSpec *(*get_buddy_icon_spec)(PurpleProtocol *protocol); + PurpleWhiteboardOps *(*get_whiteboard_ops)(PurpleProtocol *protocol); void (*login)(PurpleAccount *account);
void (*close)(PurpleConnection *connection);
GList *(*status_types)(PurpleAccount *account);
- const char *(*list_icon)(PurpleAccount *account, PurpleBuddy *buddy);
+ const gchar *(*list_icon)(PurpleAccount *account, PurpleBuddy *buddy); - void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
@@ -153,102 +126,144 @@
-/**************************************************************************/
-/* Protocol Object API */
-/**************************************************************************/
- * purple_protocol_get_type:
- * Returns: The #GType for #PurpleProtocol.
-GType purple_protocol_get_type(void);
* purple_protocol_get_id:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the ID of a protocol.
+ * Gets the ID of a protocol. * Returns: The ID of the protocol.
-const char *purple_protocol_get_id(const PurpleProtocol *protocol);
+const gchar *purple_protocol_get_id(PurpleProtocol *protocol); * purple_protocol_get_name:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the translated name of a protocol.
+ * Gets the translated name of a protocol. * Returns: The translated name of the protocol.
-const char *purple_protocol_get_name(const PurpleProtocol *protocol);
+const gchar *purple_protocol_get_name(PurpleProtocol *protocol); * purple_protocol_get_options:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the options of a protocol.
+ * Gets the options of a protocol. * Returns: The options of the protocol.
-PurpleProtocolOptions purple_protocol_get_options(const PurpleProtocol *protocol);
+PurpleProtocolOptions purple_protocol_get_options(PurpleProtocol *protocol); * purple_protocol_get_user_splits:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the user splits of a protocol.
+ * Gets the user splits of a protocol. - * Returns: (element-type PurpleAccountUserSplit) (transfer none): The user
+ * Returns: (element-type PurpleAccountUserSplit) (transfer full): The user * splits of the protocol.
-GList *purple_protocol_get_user_splits(const PurpleProtocol *protocol);
+GList *purple_protocol_get_user_splits(PurpleProtocol *protocol); * purple_protocol_get_account_options:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the account options for a protocol.
+ * Gets the account options for a protocol. - * Returns: (element-type PurpleAccountOption) (transfer none): The account
+ * Returns: (element-type PurpleAccountOption) (transfer full): The account * options for the protocol.
-GList *purple_protocol_get_account_options(const PurpleProtocol *protocol);
+GList *purple_protocol_get_account_options(PurpleProtocol *protocol); * purple_protocol_get_icon_spec:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the icon spec of a protocol.
+ * Gets the icon spec of a protocol. - * Returns: The icon spec of the protocol.
+ * Returns: (transfer full): The icon spec of the protocol. -PurpleBuddyIconSpec *purple_protocol_get_icon_spec(const PurpleProtocol *protocol);
+PurpleBuddyIconSpec *purple_protocol_get_icon_spec(PurpleProtocol *protocol); * purple_protocol_get_whiteboard_ops:
- * @protocol: The protocol.
+ * @protocol: The #PurpleProtocol instance. - * Returns the whiteboard ops of a protocol.
+ * Gets the whiteboard ops of a protocol. * Returns: (transfer none): The whiteboard ops of the protocol.
-PurpleWhiteboardOps *purple_protocol_get_whiteboard_ops(const PurpleProtocol *protocol);
+PurpleWhiteboardOps *purple_protocol_get_whiteboard_ops(PurpleProtocol *protocol); -/**************************************************************************/
-/* Protocol Class API */
-/**************************************************************************/
+ * purple_protocol_login: + * @protocol: The #PurpleProtocol instance. + * @account: The #PurpleAccount to login. + * Logs @account in using @protocol. +void purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account); + * purple_protocol_close: + * @protocol: The #PurpleProtocol instance. + * @connection: The #PurpleConnection to close. + * Closes @connection using @protocol. +void purple_protocol_close(PurpleProtocol *protocol, PurpleConnection *connection); -void purple_protocol_class_login(PurpleProtocol *protocol, PurpleAccount *account);
-void purple_protocol_class_close(PurpleProtocol *protocol, PurpleConnection *connection);
+ * purple_protocol_get_status_types: + * @protocol: The #PurpleProtocol instance. + * @account: The #PurpleAccount instance. + * Gets all of the #PurpleStatusType's for @account which uses @protocol. + * Returns: (transfer full) (element-type PurpleStatusType): A list of the + * available PurpleStatusType's for @account with @protocol. +GList *purple_protocol_get_status_types(PurpleProtocol *protocol, PurpleAccount *account); -GList *purple_protocol_class_status_types(PurpleProtocol *protocol,
- PurpleAccount *account);
-const char *purple_protocol_class_list_icon(PurpleProtocol *protocol,
- PurpleAccount *account, PurpleBuddy *buddy);
+ * purple_protocol_get_list_icon: + * @protocol: The #PurpleProtocol instance. + * @account: The #PurpleAccount instance. + * @buddy: The #PurpleBuddy instance. + * Gets the icon to show in the contact list for @buddy on @account which uses + * Both @account and @buddy may be %NULL to get the default icon for @protocol. + * Returns: The name of the icon file to use in the contact list for @buddy. +const gchar *purple_protocol_get_list_icon(PurpleProtocol *protocol, PurpleAccount *account, PurpleBuddy *buddy); --- a/libpurple/protocols/bonjour/bonjour.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/bonjour/bonjour.c Mon Mar 08 23:22:02 2021 -0600
@@ -202,6 +202,43 @@
return BONJOUR_ICON_NAME;
+bonjour_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *option; + /* Creating the options for the protocol */ + option = purple_account_option_int_new(_("Local Port"), "port", + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("First name"), "first", + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Last name"), "last", + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Email"), "email", ""); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("AIM Account"), "AIM", ""); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("XMPP Account"), "jid", ""); + opts = g_list_append(opts, option); +static PurpleBuddyIconSpec * +bonjour_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) { + return purple_buddy_icon_spec_new("png,gif,jpeg", + PURPLE_ICON_SCALE_DISPLAY); bonjour_send_im(PurpleProtocolIM *im, PurpleConnection *connection, PurpleMessage *msg)
@@ -639,34 +676,6 @@
bonjour_protocol_init(BonjourProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountOption *option;
- protocol->id = "prpl-bonjour";
- protocol->name = "Bonjour";
- protocol->options = OPT_PROTO_NO_PASSWORD;
- protocol->icon_spec = purple_buddy_icon_spec_new("png,gif,jpeg",
- PURPLE_ICON_SCALE_DISPLAY);
- /* Creating the options for the protocol */
- option = purple_account_option_int_new(_("Local Port"), "port", BONJOUR_DEFAULT_PORT);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("First name"), "first", default_firstname);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Last name"), "last", default_lastname);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Email"), "email", "");
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("AIM Account"), "AIM", "");
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("XMPP Account"), "jid", "");
- protocol->account_options = g_list_append(protocol->account_options, option);
@@ -678,6 +687,9 @@
protocol_class->close = bonjour_close;
protocol_class->status_types = bonjour_status_types;
protocol_class->list_icon = bonjour_list_icon;
+ protocol_class->get_account_options = bonjour_protocol_get_account_options; + protocol_class->get_buddy_icon_spec = bonjour_protocol_get_buddy_icon_spec; @@ -734,6 +746,16 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
bonjour_protocol_xfer_iface_init));
+bonjour_protocol_new(void) { + return PURPLE_PROTOCOL(g_object_new( + "options", OPT_PROTO_NO_PASSWORD, static PurplePluginInfo *
plugin_query(GError **error)
@@ -761,7 +783,7 @@
xep_xfer_register(G_TYPE_MODULE(plugin));
- my_protocol = g_object_new(BONJOUR_TYPE_PROTOCOL, NULL);
+ my_protocol = bonjour_protocol_new(); if(!purple_protocol_manager_register(manager, my_protocol, error)) {
g_clear_object(&my_protocol);
--- a/libpurple/protocols/facebook/facebook.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/facebook/facebook.c Mon Mar 08 23:22:02 2021 -0600
@@ -958,6 +958,39 @@
+fb_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *opt; + opt = purple_account_option_int_new(_("Buddy list sync interval"), + opts = g_list_prepend(opts, opt); + opt = purple_account_option_bool_new(_("Mark messages as read on focus"), + opts = g_list_prepend(opts, opt); + opt = purple_account_option_bool_new(_("Mark messages as read only when available"), + "mark-read-available", FALSE); + opts = g_list_prepend(opts, opt); + opt = purple_account_option_bool_new(_("Show self messages"), + opts = g_list_prepend(opts, opt); + opt = purple_account_option_bool_new(_("Show unread messages"), + opts = g_list_prepend(opts, opt); + opt = purple_account_option_bool_new(_("Open new group chats with " + "group-chat-open", TRUE); + opts = g_list_prepend(opts, opt); + return g_list_reverse(opts); fb_login(PurpleAccount *acct)
@@ -1524,41 +1557,7 @@
-facebook_protocol_init(FacebookProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountOption *opt;
- protocol->id = FB_PROTOCOL_ID;
- protocol->name = "Facebook";
- protocol->options = OPT_PROTO_CHAT_TOPIC;
- opt = purple_account_option_int_new(_("Buddy list sync interval"),
- opts = g_list_prepend(opts, opt);
- opt = purple_account_option_bool_new(_("Mark messages as read on focus"),
- opts = g_list_prepend(opts, opt);
- opt = purple_account_option_bool_new(_("Mark messages as read only when available"),
- "mark-read-available", FALSE);
- opts = g_list_prepend(opts, opt);
- opt = purple_account_option_bool_new(_("Show self messages"),
- opts = g_list_prepend(opts, opt);
- opt = purple_account_option_bool_new(_("Show unread messages"),
- opts = g_list_prepend(opts, opt);
- opt = purple_account_option_bool_new(_("Open new group chats with "
- "group-chat-open", TRUE);
- opts = g_list_prepend(opts, opt);
- protocol->account_options = g_list_reverse(opts);
+facebook_protocol_init(FacebookProtocol *self) { @@ -1566,6 +1565,8 @@
PurpleProtocolClass *protocol_class = PURPLE_PROTOCOL_CLASS(klass);
+ protocol_class->get_account_options = fb_get_account_options; protocol_class->login = fb_login;
protocol_class->close = fb_close;
protocol_class->status_types = fb_status_types;
@@ -1643,13 +1644,13 @@
g_return_if_fail(fb_cmds == NULL);
id = purple_cmd_register("kick", "s", PURPLE_CMD_P_PROTOCOL, cflags,
- fb_protocol->id, fb_cmd_kick,
+ FB_PROTOCOL_ID, fb_cmd_kick, _("kick: Kick someone from the chat"),
fb_cmds = g_slist_prepend(fb_cmds, GUINT_TO_POINTER(id));
id = purple_cmd_register("leave", "", PURPLE_CMD_P_PROTOCOL, cflags,
- fb_protocol->id, fb_cmd_leave,
+ FB_PROTOCOL_ID, fb_cmd_leave, _("leave: Leave the chat"),
fb_cmds = g_slist_prepend(fb_cmds, GUINT_TO_POINTER(id));
@@ -1692,7 +1693,11 @@
PurpleProtocolManager *manager = purple_protocol_manager_get_default();
facebook_protocol_register_type(G_TYPE_MODULE(plugin));
- fb_protocol = g_object_new(FACEBOOK_TYPE_PROTOCOL, NULL);
+ fb_protocol = g_object_new(FACEBOOK_TYPE_PROTOCOL, + "options", OPT_PROTO_CHAT_TOPIC, if(!purple_protocol_manager_register(manager, fb_protocol, error)) {
g_clear_object(&fb_protocol);
--- a/libpurple/protocols/gg/gg.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/gg/gg.c Mon Mar 08 23:22:02 2021 -0600
@@ -49,7 +49,6 @@
/* ---------------------------------------------------------------------- */
static PurpleProtocol *my_protocol = NULL;
-static PurpleAccountOption *ggp_server_option;
/* ---------------------------------------------------------------------- */
@@ -646,6 +645,62 @@
+static PurpleBuddyIconSpec * +ggp_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) { + return purple_buddy_icon_spec_new("png", + PURPLE_ICON_SCALE_DISPLAY | + PURPLE_ICON_SCALE_SEND); +ggp_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *option = NULL; + PurpleKeyValuePair *kvp = NULL; + GList *encryption_options = NULL; + GList *protocol_version = NULL; + option = purple_account_option_string_new(_("GG server"), "gg_server", ""); + opts = g_list_append(opts, option); + /* setup encryption options */ + kvp = purple_key_value_pair_new(_("Use encryption if available"), + encryption_options = g_list_append(encryption_options, kvp); + kvp = purple_key_value_pair_new(_("Require encryption"), "require_tls"); + encryption_options = g_list_append(encryption_options, kvp); + kvp = purple_key_value_pair_new(_("Don't use encryption"), "none"); + encryption_options = g_list_append(encryption_options, kvp); + option = purple_account_option_list_new(_("Connection security"), + "encryption", encryption_options); + opts = g_list_append(opts, option); + /* setup the protocol version */ + kvp = purple_key_value_pair_new(_("Default"), "default"); + protocol_version = g_list_append(protocol_version, kvp); + kvp = purple_key_value_pair_new("GG 10", "gg10"); + protocol_version = g_list_append(protocol_version, kvp); + kvp = purple_key_value_pair_new("GG 11", "gg11"); + protocol_version = g_list_append(protocol_version, kvp); + option = purple_account_option_list_new(_("Protocol version"), + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Show links from strangers"), + "show_links_from_strangers", 1); + opts = g_list_append(opts, option); ggp_normalize(PurpleProtocolClient *client, PurpleAccount *account,
@@ -1026,52 +1081,6 @@
ggp_protocol_init(GGPProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountOption *option;
- GList *encryption_options = NULL;
- GList *protocol_version = NULL;
- protocol->id = "prpl-gg";
- protocol->name = "Gadu-Gadu";
- protocol->icon_spec = purple_buddy_icon_spec_new("png",
- PURPLE_ICON_SCALE_DISPLAY |
- PURPLE_ICON_SCALE_SEND);
- option = purple_account_option_string_new(_("GG server"),
- protocol->account_options = g_list_append(protocol->account_options,
- ggp_server_option = option;
-#define ADD_VALUE(list, desc, v) { \
- PurpleKeyValuePair *kvp = purple_key_value_pair_new_full((desc), g_strdup((v)), g_free); \
- list = g_list_append(list, kvp); \
- ADD_VALUE(encryption_options, _("Use encryption if available"),
- ADD_VALUE(encryption_options, _("Require encryption"), "require_tls");
- ADD_VALUE(encryption_options, _("Don't use encryption"), "none");
- option = purple_account_option_list_new(_("Connection security"),
- "encryption", encryption_options);
- protocol->account_options = g_list_append(protocol->account_options,
- ADD_VALUE(protocol_version, _("Default"), "default");
- ADD_VALUE(protocol_version, "GG 10", "gg10");
- ADD_VALUE(protocol_version, "GG 11", "gg11");
- option = purple_account_option_list_new(_("Protocol version"),
- "protocol_version", protocol_version);
- protocol->account_options = g_list_append(protocol->account_options,
- option = purple_account_option_bool_new(_("Show links from strangers"),
- "show_links_from_strangers", 1);
- protocol->account_options = g_list_append(protocol->account_options,
@@ -1083,6 +1092,9 @@
protocol_class->close = ggp_close;
protocol_class->status_types = ggp_status_types;
protocol_class->list_icon = ggp_list_icon;
+ protocol_class->get_account_options = ggp_protocol_get_account_options; + protocol_class->get_buddy_icon_spec = ggp_protocol_get_buddy_icon_spec; @@ -1184,6 +1196,15 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
ggp_protocol_xfer_iface_init));
+ggp_protocol_new(void) { + return PURPLE_PROTOCOL(g_object_new( plugin_extra(PurplePlugin *plugin)
@@ -1224,7 +1245,7 @@
ggp_xfer_register(G_TYPE_MODULE(plugin));
- my_protocol = g_object_new(GGP_TYPE_PROTOCOL, NULL);
+ my_protocol = ggp_protocol_new(); if(!purple_protocol_manager_register(manager, my_protocol, error)) {
g_clear_object(&my_protocol);
@@ -1238,7 +1259,7 @@
ggp_resolver_purple_setup();
- ggp_servconn_setup(ggp_server_option);
+ ggp_servconn_setup(NULL); ggp_message_setup_global();
--- a/libpurple/protocols/gg/servconn.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/gg/servconn.c Mon Mar 08 23:22:02 2021 -0600
@@ -57,8 +57,10 @@
g_list_free_full(extra, g_free);
- purple_account_option_string_set_hints(global_data.server_option,
- ggp_servconn_get_servers());
+ if(server_option != NULL) { + purple_account_option_string_set_hints(global_data.server_option, + ggp_servconn_get_servers()); void ggp_servconn_cleanup(void)
--- a/libpurple/protocols/irc/irc.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/irc/irc.c Mon Mar 08 23:22:02 2021 -0600
@@ -357,6 +357,63 @@
+irc_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *option; + option = purple_account_option_int_new(_("Port"), "port", + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Encodings"), "encoding", + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Auto-detect incoming UTF-8"), + IRC_DEFAULT_AUTODETECT); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Ident name"), "username", ""); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Real name"), "realname", ""); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Quit message"), "quitmsg", + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Use SSL"), "ssl", FALSE); + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Authenticate with SASL"), + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Allow plaintext SASL auth over " + "unencrypted connection"), + "auth_plain_in_clear", FALSE); + opts = g_list_append(opts, option); +irc_protocol_get_user_splits(PurpleProtocol *protocol) { + PurpleAccountUserSplit *split; + split = purple_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, + return g_list_append(NULL, split); static GList *irc_status_types(PurpleAccount *account)
@@ -972,50 +1029,6 @@
irc_protocol_init(IRCProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountUserSplit *split;
- PurpleAccountOption *option;
- protocol->id = "prpl-irc";
- protocol->name = "IRC";
- protocol->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL |
- OPT_PROTO_SLASH_COMMANDS_NATIVE;
- split = purple_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, '@');
- protocol->user_splits = g_list_append(protocol->user_splits, split);
- option = purple_account_option_int_new(_("Port"), "port", IRC_DEFAULT_PORT);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Encodings"), "encoding", IRC_DEFAULT_CHARSET);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Auto-detect incoming UTF-8"), "autodetect_utf8", IRC_DEFAULT_AUTODETECT);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Ident name"), "username", "");
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Real name"), "realname", "");
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Quit message"), "quitmsg", IRC_DEFAULT_QUIT);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Use SSL"), "ssl", FALSE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Authenticate with SASL"), "sasl", FALSE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(
- _("Allow plaintext SASL auth over unencrypted connection"),
- "auth_plain_in_clear", FALSE);
- protocol->account_options = g_list_append(protocol->account_options, option);
@@ -1027,6 +1040,9 @@
protocol_class->close = irc_close;
protocol_class->status_types = irc_status_types;
protocol_class->list_icon = irc_blist_icon;
+ protocol_class->get_account_options = irc_protocol_get_account_options; + protocol_class->get_user_splits = irc_protocol_get_user_splits; @@ -1107,6 +1123,17 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
irc_protocol_xfer_iface_init));
+irc_protocol_new(void) { + return PURPLE_PROTOCOL(g_object_new( + "options", OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL | + OPT_PROTO_SLASH_COMMANDS_NATIVE, static PurplePluginInfo *
plugin_query(GError **error)
@@ -1134,7 +1161,7 @@
irc_xfer_register(G_TYPE_MODULE(plugin));
- _irc_protocol = g_object_new(IRC_TYPE_PROTOCOL, NULL);
+ _irc_protocol = irc_protocol_new(); if(!purple_protocol_manager_register(manager, _irc_protocol, error)) {
g_clear_object(&_irc_protocol);
--- a/libpurple/protocols/jabber/jabber.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/jabber/jabber.c Mon Mar 08 23:22:02 2021 -0600
@@ -3789,7 +3789,7 @@
acct_id = g_hash_table_lookup(params, "account");
- acct = find_acct(protocol->id, acct_id);
+ acct = find_acct(XMPP_PROTOCOL_ID, acct_id); @@ -4076,24 +4076,16 @@
+static PurpleBuddyIconSpec * +jabber_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) { + return purple_buddy_icon_spec_new("png", + PURPLE_ICON_SCALE_SEND | + PURPLE_ICON_SCALE_DISPLAY); -jabber_protocol_init(JabberProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- protocol->id = "prpl-jabber";
- protocol->name = "XMPP";
- protocol->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
- OPT_PROTO_PASSWORD_OPTIONAL |
- OPT_PROTO_SLASH_COMMANDS_NATIVE;
- protocol->icon_spec = purple_buddy_icon_spec_new("png",
- PURPLE_ICON_SCALE_SEND |
- PURPLE_ICON_SCALE_DISPLAY);
+jabber_protocol_init(JabberProtocol *self) { @@ -4101,6 +4093,8 @@
PurpleProtocolClass *protocol_class = PURPLE_PROTOCOL_CLASS(klass);
+ protocol_class->get_buddy_icon_spec = jabber_protocol_get_buddy_icon_spec; protocol_class->login = jabber_login;
protocol_class->close = jabber_close;
protocol_class->status_types = jabber_status_types;
@@ -4299,7 +4293,7 @@
jabber_si_xfer_register(G_TYPE_MODULE(plugin));
- xmpp_protocol = g_object_new(XMPP_TYPE_PROTOCOL, NULL);
+ xmpp_protocol = xmpp_protocol_new(); if(!purple_protocol_manager_register(manager, xmpp_protocol, error)) {
g_clear_object(&xmpp_protocol);
--- a/libpurple/protocols/jabber/xmpp.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/jabber/xmpp.c Mon Mar 08 23:22:02 2021 -0600
@@ -20,84 +20,96 @@
#include <glib/gi18n-lib.h>
-xmpp_protocol_init(XMPPProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountUserSplit *split;
+xmpp_protocol_get_account_options(PurpleProtocol *protocol) { PurpleAccountOption *option;
- GList *encryption_values = NULL;
+ PurpleKeyValuePair *kvp = NULL; + GList *opts = NULL, *encryption_values = NULL; - /* Translators: 'domain' is used here in the context of Internet domains, e.g. pidgin.im */
- split = purple_account_user_split_new(_("Domain"), NULL, '@');
- purple_account_user_split_set_reverse(split, FALSE);
- protocol->user_splits = g_list_append(protocol->user_splits, split);
+ /* build the list of encryption types we support */ + kvp = purple_key_value_pair_new(_("Require encryption"), "require_tls"); + encryption_values = g_list_append(encryption_values, kvp); - split = purple_account_user_split_new(_("Resource"), "", '/');
- purple_account_user_split_set_reverse(split, FALSE);
- protocol->user_splits = g_list_append(protocol->user_splits, split);
+ kvp = purple_key_value_pair_new(_("Use encryption if available"), + encryption_values = g_list_append(encryption_values, kvp); -#define ADD_VALUE(list, desc, v) { \
- PurpleKeyValuePair *kvp = purple_key_value_pair_new_full((desc), g_strdup((v)), g_free); \
- list = g_list_prepend(list, kvp); \
- ADD_VALUE(encryption_values, _("Require encryption"), "require_tls");
- ADD_VALUE(encryption_values, _("Use encryption if available"), "opportunistic_tls");
- ADD_VALUE(encryption_values, _("Use old-style SSL"), "old_ssl");
- encryption_values = g_list_reverse(encryption_values);
+ kvp = purple_key_value_pair_new(_("Use old-style SSL"), "old_ssl"); + encryption_values = g_list_append(encryption_values, kvp);
- option = purple_account_option_list_new(_("Connection security"), "connection_security", encryption_values);
- protocol->account_options = g_list_append(protocol->account_options,
+ /* build all the options */ + option = purple_account_option_list_new(_("Connection security"), + opts = g_list_append(opts, option); - option = purple_account_option_bool_new(
- _("Allow plaintext auth over unencrypted streams"),
- "auth_plain_in_clear", FALSE);
- protocol->account_options = g_list_append(protocol->account_options,
+ option = purple_account_option_bool_new(_("Allow plaintext auth over " + "unencrypted streams"), + "auth_plain_in_clear", FALSE); + opts = g_list_append(opts, option); option = purple_account_option_int_new(_("Connect port"), "port", 5222);
- protocol->account_options = g_list_append(protocol->account_options,
+ opts = g_list_append(opts, option); option = purple_account_option_string_new(_("Connect server"),
- "connect_server", NULL);
- protocol->account_options = g_list_append(protocol->account_options,
+ "connect_server", NULL); + opts = g_list_append(opts, option); option = purple_account_option_string_new(_("File transfer proxies"),
- protocol->account_options = g_list_append(protocol->account_options,
+ opts = g_list_append(opts, option); - option = purple_account_option_string_new(_("BOSH URL"),
- protocol->account_options = g_list_append(protocol->account_options,
+ option = purple_account_option_string_new(_("BOSH URL"), "bosh_url", NULL); + opts = g_list_append(opts, option); /* this should probably be part of global smiley theme settings
option = purple_account_option_bool_new(_("Show Custom Smileys"),
- "custom_smileys", TRUE);
- protocol->account_options = g_list_append(protocol->account_options,
+ "custom_smileys", TRUE); + opts = g_list_append(opts, option); +xmpp_protocol_get_user_splits(PurpleProtocol *protocol) { + PurpleAccountUserSplit *split; + /* Translators: 'domain' is used here in the context of Internet domains, + split = purple_account_user_split_new(_("Domain"), NULL, '@'); + purple_account_user_split_set_reverse(split, FALSE); + splits = g_list_append(splits, split); + split = purple_account_user_split_new(_("Resource"), "", '/'); + purple_account_user_split_set_reverse(split, FALSE); + splits = g_list_append(splits, split); +xmpp_protocol_init(XMPPProtocol *self) { purple_prefs_remove("/plugins/prpl/jabber");
-xmpp_protocol_class_init(G_GNUC_UNUSED XMPPProtocolClass *klass)
+xmpp_protocol_class_init(XMPPProtocolClass *klass) { + PurpleProtocolClass *protocol_class = PURPLE_PROTOCOL_CLASS(klass); + protocol_class->get_account_options = xmpp_protocol_get_account_options; + protocol_class->get_user_splits = xmpp_protocol_get_user_splits; @@ -114,3 +126,23 @@
xmpp_protocol_register_type(G_TYPE_MODULE(plugin));
+xmpp_protocol_new(void) { + PurpleProtocolOptions options; + options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME | + OPT_PROTO_MAIL_CHECK | OPT_PROTO_SLASH_COMMANDS_NATIVE; + options |= OPT_PROTO_PASSWORD_OPTIONAL; + return PURPLE_PROTOCOL(g_object_new( + "id", XMPP_PROTOCOL_ID, \ No newline at end of file
--- a/libpurple/protocols/jabber/xmpp.h Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/jabber/xmpp.h Mon Mar 08 23:22:02 2021 -0600
@@ -25,6 +25,8 @@
+#define XMPP_PROTOCOL_ID "prpl-jabber" #define XMPP_TYPE_PROTOCOL (xmpp_protocol_get_type())
#define XMPP_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XMPP_TYPE_PROTOCOL, XMPPProtocol))
#define XMPP_PROTOCOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XMPP_TYPE_PROTOCOL, XMPPProtocolClass))
@@ -48,6 +50,9 @@
void xmpp_protocol_register(PurplePlugin *plugin);
+PurpleProtocol *xmpp_protocol_new(void); * Returns the GType for the XMPPProtocol object.
--- a/libpurple/protocols/novell/novell.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/novell/novell.c Mon Mar 08 23:22:02 2021 -0600
@@ -2831,6 +2831,22 @@
+novell_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *option; + option = purple_account_option_string_new(_("Server address"), "server", + opts = g_list_append(opts, option); + option = purple_account_option_int_new(_("Server port"), "port", + opts = g_list_append(opts, option); novell_tooltip_text(PurpleProtocolClient *client, PurpleBuddy *buddy,
PurpleNotifyUserInfo *user_info, gboolean full)
@@ -3507,19 +3523,6 @@
novell_protocol_init(NovellProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountOption *option;
- protocol->id = "prpl-novell";
- protocol->name = "GroupWise";
- option = purple_account_option_string_new(_("Server address"), "server", NULL);
- protocol->account_options =
- g_list_append(protocol->account_options, option);
- option = purple_account_option_int_new(_("Server port"), "port", DEFAULT_PORT);
- protocol->account_options =
- g_list_append(protocol->account_options, option);
@@ -3531,6 +3534,8 @@
protocol_class->close = novell_close;
protocol_class->status_types = novell_status_types;
protocol_class->list_icon = novell_list_icon;
+ protocol_class->get_account_options = novell_protocol_get_account_options; @@ -3607,6 +3612,15 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_PRIVACY,
novell_protocol_privacy_iface_init));
+novell_protocol_new(void) { + return PURPLE_PROTOCOL(g_object_new( static PurplePluginInfo *
plugin_query(GError **error)
@@ -3632,7 +3646,7 @@
novell_protocol_register_type(G_TYPE_MODULE(plugin));
- my_protocol = g_object_new(NOVELL_TYPE_PROTOCOL, NULL);
+ my_protocol = novell_protocol_new(); if(!purple_protocol_manager_register(manager, my_protocol, error)) {
g_clear_object(&my_protocol);
--- a/libpurple/protocols/null/nullprpl.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/null/nullprpl.c Mon Mar 08 23:22:02 2021 -0600
@@ -205,6 +205,43 @@
+null_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *option; + option = purple_account_option_string_new( + _("Example option"), /* text shown to user */ + "example", /* pref name */ + "default"); /* default value */ + return g_list_append(NULL, option); +static PurpleBuddyIconSpec * +null_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) { + return purple_buddy_icon_spec_new( + "png,jpg,gif", /* format */ + 10000, /* max_filesize */ + PURPLE_ICON_SCALE_DISPLAY /* scale_rules */ +null_protocol_get_user_splits(PurpleProtocol *protocol) { + PurpleAccountUserSplit *split; + split = purple_account_user_split_new( + _("Example user split"), /* text shown to user */ + "default", /* default value */ + '@'); /* field separator */ + return g_list_append(NULL, split); null_status_text(PurpleProtocolClient *client, PurpleBuddy *buddy) {
purple_debug_info("nullprpl", "getting %s's status text for %s\n",
@@ -1048,36 +1085,6 @@
null_protocol_init(NullProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountUserSplit *split;
- PurpleAccountOption *option;
- protocol->id = "prpl-null";
- protocol->name = "Null - Testing Protocol";
- protocol->options = OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC;
- protocol->icon_spec = purple_buddy_icon_spec_new(
- "png,jpg,gif", /* format */
- 10000, /* max_filesize */
- PURPLE_ICON_SCALE_DISPLAY /* scale_rules */
- /* see accountopt.h for information about user splits and protocol
- split = purple_account_user_split_new(
- _("Example user split"), /* text shown to user */
- "default", /* default value */
- '@'); /* field separator */
- option = purple_account_option_string_new(
- _("Example option"), /* text shown to user */
- "example", /* pref name */
- "default"); /* default value */
- protocol->user_splits = g_list_append(NULL, split);
- protocol->account_options = g_list_append(NULL, option);
@@ -1094,6 +1101,10 @@
protocol_class->close = null_close;
protocol_class->status_types = null_status_types;
protocol_class->list_icon = null_list_icon;
+ protocol_class->get_account_options = null_protocol_get_account_options; + protocol_class->get_buddy_icon_spec = null_protocol_get_buddy_icon_spec; + protocol_class->get_user_splits = null_protocol_get_user_splits; @@ -1199,6 +1210,16 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_ROOMLIST,
null_protocol_roomlist_iface_init));
+null_protocol_new(void) { + return PURPLE_PROTOCOL(g_object_new( + "name", "Null - Testing Protocol", + "options", OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC, static PurplePluginInfo *
plugin_query(GError **error)
@@ -1230,7 +1251,7 @@
null_protocol_register_type(G_TYPE_MODULE(plugin));
/* add the protocol to the core */
- my_protocol = g_object_new(NULL_TYPE_PROTOCOL, NULL);
+ my_protocol = null_protocol_new(); if(!purple_protocol_manager_register(manager, my_protocol, error)) {
g_clear_object(&my_protocol);
--- a/libpurple/protocols/sametime/sametime.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/sametime/sametime.c Mon Mar 08 23:22:02 2021 -0600
@@ -3118,6 +3118,49 @@
+mw_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *opt; + /* port to connect to */ + opt = purple_account_option_int_new(_("Port"), MW_KEY_PORT, + MW_PLUGIN_DEFAULT_PORT); + opts = g_list_append(opts, opt); + { /* copy the old force login setting from prefs if it's + there. Don't delete the preference, since there may be more + than one account that wants to check for it. */ + const gchar *label = _("Force login (ignore server redirects)"); + if (purple_prefs_exists(MW_PROTOCOL_OPT_FORCE_LOGIN)) + b = purple_prefs_get_bool(MW_PROTOCOL_OPT_FORCE_LOGIN); + opt = purple_account_option_bool_new(label, MW_KEY_FORCE, b); + opts = g_list_append(opts, opt); + /* pretend to be Sametime Connect */ + opt = purple_account_option_bool_new(_("Hide client identity"), + MW_KEY_FAKE_IT, FALSE); + opts = g_list_append(opts, opt); +mw_protocol_get_user_splits(PurpleProtocol *protocol) { + PurpleAccountUserSplit *split; + /* set up account ID as user:server */ + split = purple_account_user_split_new(_("Server"), + MW_PLUGIN_DEFAULT_HOST, ':'); + splits = g_list_append(splits, split); mw_protocol_list_emblem(PurpleProtocolClient *client, PurpleBuddy *b) {
@@ -5209,53 +5252,14 @@
mw_protocol_init(mwProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountUserSplit *split;
- PurpleAccountOption *opt;
- protocol->id = PROTOCOL_ID;
- protocol->name = PROTOCOL_NAME;
/* set up the preferences */
purple_prefs_add_none(MW_PROTOCOL_OPT_BASE);
purple_prefs_add_int(MW_PROTOCOL_OPT_BLIST_ACTION,
- /* set up account ID as user:server */
- split = purple_account_user_split_new(_("Server"),
- MW_PLUGIN_DEFAULT_HOST, ':');
- protocol->user_splits = g_list_append(protocol->user_splits, split);
/* remove dead preferences */
purple_prefs_remove(MW_PROTOCOL_OPT_PSYCHIC);
purple_prefs_remove(MW_PROTOCOL_OPT_SAVE_DYNAMIC);
- /* port to connect to */
- opt = purple_account_option_int_new(_("Port"), MW_KEY_PORT,
- MW_PLUGIN_DEFAULT_PORT);
- l = g_list_append(l, opt);
- { /* copy the old force login setting from prefs if it's
- there. Don't delete the preference, since there may be more
- than one account that wants to check for it. */
- const char *label = _("Force login (ignore server redirects)");
- if (purple_prefs_exists(MW_PROTOCOL_OPT_FORCE_LOGIN))
- b = purple_prefs_get_bool(MW_PROTOCOL_OPT_FORCE_LOGIN);
- opt = purple_account_option_bool_new(label, MW_KEY_FORCE, b);
- l = g_list_append(l, opt);
- /* pretend to be Sametime Connect */
- opt = purple_account_option_bool_new(_("Hide client identity"),
- MW_KEY_FAKE_IT, FALSE);
- l = g_list_append(l, opt);
- protocol->account_options = l;
@@ -5267,6 +5271,9 @@
protocol_class->close = mw_protocol_close;
protocol_class->status_types = mw_protocol_status_types;
protocol_class->list_icon = mw_protocol_list_icon;
+ protocol_class->get_account_options = mw_protocol_get_account_options; + protocol_class->get_user_splits = mw_protocol_get_user_splits; @@ -5368,6 +5375,15 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
mw_protocol_xfer_iface_init));
+ return PURPLE_PROTOCOL(g_object_new( static PurplePluginInfo *
plugin_query(GError **error)
@@ -5401,7 +5417,7 @@
mw_xfer_register_type(G_TYPE_MODULE(plugin));
- my_protocol = g_object_new(MW_TYPE_PROTOCOL, NULL);
+ my_protocol = mw_protocol_new(); if(!purple_protocol_manager_register(manager, my_protocol, error)) {
g_clear_object(&my_protocol);
--- a/libpurple/protocols/zephyr/zephyr.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/protocols/zephyr/zephyr.c Mon Mar 08 23:22:02 2021 -0600
@@ -1258,6 +1258,49 @@
+zephyr_protocol_get_account_options(PurpleProtocol *protocol) { + PurpleAccountOption *option; + const gchar *tmp = get_exposure_level(); + option = purple_account_option_bool_new(_("Use tzc"), "use_tzc", FALSE); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("tzc command"), "tzc_command", + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Export to .anyone"), + "write_anyone", FALSE); + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Export to .zephyr.subs"), + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Import from .anyone"), + opts = g_list_append(opts, option); + option = purple_account_option_bool_new(_("Import from .zephyr.subs"), + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Realm"), "realm", ""); + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Exposure"), "exposure_level", + opts = g_list_append(opts, option); + option = purple_account_option_string_new(_("Encoding"), "encoding", + ZEPHYR_FALLBACK_CHARSET); + opts = g_list_append(opts, option); zephyr_send_typing(G_GNUC_UNUSED PurpleProtocolIM *im, PurpleConnection *gc, const char *who, PurpleIMTypingState state)
@@ -1576,41 +1619,6 @@
zephyr_protocol_init(ZephyrProtocol *self)
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountOption *option;
- const gchar *tmp = get_exposure_level();
- protocol->id = "prpl-zephyr";
- protocol->name = "Zephyr";
- protocol->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD;
- option = purple_account_option_bool_new(_("Use tzc"), "use_tzc", FALSE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("tzc command"), "tzc_command", "/usr/bin/tzc -e %s");
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Export to .anyone"), "write_anyone", FALSE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Export to .zephyr.subs"), "write_zsubs", FALSE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Import from .anyone"), "read_anyone", TRUE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_bool_new(_("Import from .zephyr.subs"), "read_zsubs", TRUE);
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Realm"), "realm", "");
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Exposure"), "exposure_level",
- protocol->account_options = g_list_append(protocol->account_options, option);
- option = purple_account_option_string_new(_("Encoding"), "encoding", ZEPHYR_FALLBACK_CHARSET);
- protocol->account_options = g_list_append(protocol->account_options, option);
@@ -1623,6 +1631,8 @@
protocol_class->close = zephyr_close;
protocol_class->status_types = zephyr_status_types;
protocol_class->list_icon = zephyr_list_icon;
+ protocol_class->get_account_options = zephyr_protocol_get_account_options; @@ -1689,6 +1699,16 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_CHAT,
zephyr_protocol_chat_iface_init));
+zephyr_protocol_new(void) { + return PURPLE_PROTOCOL(g_object_new( + "options", OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD, static PurplePluginInfo *plugin_query(GError **error)
return purple_plugin_info_new(
@@ -1714,7 +1734,7 @@
zephyr_protocol_register_type(G_TYPE_MODULE(plugin));
- my_protocol = g_object_new(ZEPHYR_TYPE_PROTOCOL, NULL);
+ my_protocol = zephyr_protocol_new(); if(!purple_protocol_manager_register(manager, my_protocol, error)) {
g_clear_object(&my_protocol);
--- a/libpurple/tests/test_protocol_attention.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/tests/test_protocol_attention.c Mon Mar 08 23:22:02 2021 -0600
@@ -79,21 +79,26 @@
test_purple_protocol_attention_init(TestPurpleProtocolAttention *prplattn) {
- PurpleProtocol *prpl = PURPLE_PROTOCOL(prplattn);
- prpl->id = "prpl-attention";
test_purple_protocol_attention_class_init(TestPurpleProtocolAttentionClass *klass) {
+static TestPurpleProtocolAttention * +test_purple_protocol_attention_new(void) { + return (TestPurpleProtocolAttention *)g_object_new( + test_purple_protocol_attention_get_type(), + "id", "prpl-attention", /******************************************************************************
*****************************************************************************/
test_purple_protocol_attention_can_send(void) {
- TestPurpleProtocolAttention *attn = g_object_new(test_purple_protocol_attention_get_type(), NULL);
+ TestPurpleProtocolAttention *attn = test_purple_protocol_attention_new(); PurpleAccount *a = purple_account_new("prpl-attn-can-send", "prpl-attn");
PurpleConnection *c = g_object_new(PURPLE_TYPE_CONNECTION, "account", a, NULL);
--- a/libpurple/tests/test_protocol_xfer.c Mon Mar 08 20:19:07 2021 -0600
+++ b/libpurple/tests/test_protocol_xfer.c Mon Mar 08 23:22:02 2021 -0600
@@ -88,21 +88,26 @@
test_purple_protocol_xfer_init(TestPurpleProtocolXfer *prplxfer) {
- PurpleProtocol *prpl = PURPLE_PROTOCOL(prplxfer);
- prpl->id = "prpl-xfer";
test_purple_protocol_xfer_class_init(TestPurpleProtocolXferClass *klass) {
+static TestPurpleProtocolXfer * +test_purple_protocol_xfer_new(void) { + return (TestPurpleProtocolXfer *)g_object_new( + test_purple_protocol_xfer_get_type(), /******************************************************************************
*****************************************************************************/
test_purple_protocol_xfer_can_receive_func(void) {
- TestPurpleProtocolXfer *xfer = g_object_new(test_purple_protocol_xfer_get_type(), NULL);
+ TestPurpleProtocolXfer *xfer = test_purple_protocol_xfer_new(); PurpleAccount *a = purple_account_new("prpl-xfer-can-receive", "prpl-xfer");
PurpleConnection *c = g_object_new(PURPLE_TYPE_CONNECTION, "account", a, NULL);
@@ -112,7 +117,7 @@
actual = purple_protocol_xfer_can_receive(
PURPLE_PROTOCOL_XFER(xfer),
--- a/pidgin/gtkaccount.c Mon Mar 08 20:19:07 2021 -0600
+++ b/pidgin/gtkaccount.c Mon Mar 08 23:22:02 2021 -0600
@@ -212,6 +212,8 @@
+ purple_buddy_icon_spec_free(icon_spec); /* Show a placeholder icon */
@@ -574,6 +576,9 @@
gtk_entry_set_text(GTK_ENTRY(entry), value);
+ g_list_free_full(user_splits, + (GDestroyNotify)purple_account_user_split_destroy); gtk_entry_set_text(GTK_ENTRY(dialog->username_entry), username);
@@ -713,6 +718,8 @@
gtk_widget_hide(dialog->icon_check);
gtk_widget_hide(dialog->icon_hbox);
+ purple_buddy_icon_spec_free(icon_spec); if (dialog->account != NULL) {
@@ -766,7 +773,7 @@
PurpleAccountOption *option;
GtkWidget *vbox, *check, *entry, *combo;
+ GList *list, *node, *opts; @@ -788,9 +795,14 @@
g_list_free_full(dialog->protocol_opt_entries, (GDestroyNotify)protocol_opt_entry_free);
dialog->protocol_opt_entries = NULL;
- if (dialog->protocol == NULL ||
- purple_protocol_get_account_options(dialog->protocol) == NULL)
+ if (dialog->protocol == NULL) { + opts = purple_protocol_get_account_options(dialog->protocol); account = dialog->account;
@@ -801,7 +813,7 @@
gtk_label_new_with_mnemonic(_("Ad_vanced")), 1);
- for (l = purple_protocol_get_account_options(dialog->protocol); l != NULL; l = l->next)
+ for (l = opts; l != NULL; l = l->next) option = (PurpleAccountOption *)l->data;
@@ -978,6 +990,7 @@
g_list_append(dialog->protocol_opt_entries, opt_entry);
+ g_list_free_full(opts, (GDestroyNotify)purple_account_option_destroy); @@ -1396,6 +1409,8 @@
+ purple_buddy_icon_spec_free(icon_spec); remember = gtk_toggle_button_get_active(
@@ -2167,6 +2182,8 @@
+ purple_buddy_icon_spec_free(icon_spec); GdkPixbuf *buddyicon_pixbuf;
buddyicon_pixbuf = pidgin_pixbuf_from_image(img);
--- a/pidgin/gtkblist.c Mon Mar 08 20:19:07 2021 -0600
+++ b/pidgin/gtkblist.c Mon Mar 08 23:22:02 2021 -0600
@@ -2230,7 +2230,7 @@
- purple_protocol_class_list_icon(purple_connection_get_protocol(gc),
+ purple_protocol_get_list_icon(purple_connection_get_protocol(gc), purple_buddy_get_account(buddy), buddy);
str = g_string_new(NULL);
@@ -2688,8 +2688,12 @@
icon_spec = purple_protocol_get_icon_spec(protocol);
- if (icon_spec && icon_spec->scale_rules & PURPLE_ICON_SCALE_DISPLAY)
- purple_buddy_icon_spec_get_scaled_size(purple_protocol_get_icon_spec(protocol), &scale_width, &scale_height);
+ if (icon_spec && (icon_spec->scale_rules & PURPLE_ICON_SCALE_DISPLAY)) { + purple_buddy_icon_spec_get_scaled_size(icon_spec, &scale_width, + purple_buddy_icon_spec_free(icon_spec); if (scaled || scale_height > 200 || scale_width > 200) {
--- a/pidgin/gtkutils.c Mon Mar 08 20:19:07 2021 -0600
+++ b/pidgin/gtkutils.c Mon Mar 08 23:22:02 2021 -0600
@@ -269,7 +269,7 @@
- protoname = purple_protocol_class_list_icon(protocol, account, NULL);
+ protoname = purple_protocol_get_list_icon(protocol, account, NULL); @@ -491,7 +491,7 @@
proto = purple_connection_get_protocol(gc);
- protoname = purple_protocol_class_list_icon(proto, account, NULL);
+ protoname = purple_protocol_get_list_icon(proto, account, NULL); if (purple_strequal(protoname, protocol))
@@ -1523,11 +1523,18 @@
spec = purple_protocol_get_icon_spec(protocol);
- g_return_val_if_fail(spec->format != NULL, NULL);
+ if(spec->format == NULL) { + purple_buddy_icon_spec_free(spec); format = gdk_pixbuf_get_file_info(path, &orig_width, &orig_height);
purple_debug_warning("buddyicon", "Could not get file info of %s\n", path);
+ purple_buddy_icon_spec_free(spec); @@ -1545,6 +1552,7 @@
purple_debug_warning("buddyicon", "Could not get file contents "
"of %s: %s\n", path, error->message);
g_strfreev(protocol_formats);
+ purple_buddy_icon_spec_free(spec); @@ -1554,6 +1562,7 @@
g_strfreev(protocol_formats);
+ purple_buddy_icon_spec_free(spec); @@ -1570,6 +1579,7 @@
"conversion: %s\n", path, error->message);
g_strfreev(protocol_formats);
+ purple_buddy_icon_spec_free(spec); original = g_object_ref(pixbuf);
@@ -1638,6 +1648,7 @@
g_strfreev(protocol_formats);
g_object_unref(G_OBJECT(pixbuf));
g_object_unref(G_OBJECT(original));
+ purple_buddy_icon_spec_free(spec); @@ -1672,6 +1683,8 @@
purple_notify_error(NULL, _("Icon Error"), _("Could not set icon"), tmp, NULL);
+ purple_buddy_icon_spec_free(spec);