pidgin/pidgin

Modernize PurpleProtocol

2021-03-08, Gary Kramlich
71305a7d7423
Parents 3259645493ae
Children 9bdf61ddf211
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 @@
if (protocol != NULL)
{
- GList *iter, *entries;
- 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),
value);
}
+ g_list_free_full(splits,
+ (GDestroyNotify)purple_account_user_split_destroy);
}
if (dialog->account == NULL)
@@ -199,9 +202,10 @@
/* Protocol options */
if (protocol)
{
- GList *iter, *entries;
+ 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_assert_not_reached();
}
}
+ g_list_free_full(opts, (GDestroyNotify)purple_account_option_destroy);
}
/* XXX: Proxy options */
@@ -279,7 +284,7 @@
{
GntWidget *hbox;
PurpleProtocol *protocol;
- GList *iter, *entries;
+ GList *iter, *entries, *splits;
char *username = NULL;
if (dialog->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;
GntWidget *entry = NULL;
@@ -323,7 +329,7 @@
g_free(buf);
}
- 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);
+
if (username != NULL)
gnt_entry_set_text(GNT_ENTRY(dialog->username), username);
@@ -362,7 +370,7 @@
add_account_options(AccountEditDialog *dialog)
{
PurpleProtocol *protocol;
- GList *iter;
+ GList *iter, *opts;
GntWidget *vbox, *box;
PurpleAccount *account;
@@ -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 @@
return icon_spec;
}
+void
+purple_buddy_icon_spec_free(PurpleBuddyIconSpec *spec) {
+ if(spec == NULL) {
+ return;
+ }
+
+ g_free(spec);
+}
+
static PurpleBuddyIconSpec *
purple_buddy_icon_spec_copy(PurpleBuddyIconSpec *icon_spec)
{
@@ -1219,7 +1228,7 @@
if (type == 0) {
type = g_boxed_type_register_static("PurpleBuddyIconSpec",
(GBoxedCopyFunc)purple_buddy_icon_spec_copy,
- (GBoxedFreeFunc)g_free);
+ (GBoxedFreeFunc)purple_buddy_icon_spec_free);
}
return type;
--- 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.
+ *
+ * Frees @spec.
+ *
+ * Since: 3.0.0
+ */
+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 @@
if (!protocol)
return NULL;
- 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 (!protocol)
continue;
- 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 @@
gsize written = 0;
if(!data) {
- const char *proto = purple_protocol_class_list_icon(protocol, log->account, NULL);
+ const char *proto = purple_protocol_get_list_icon(protocol, log->account, NULL);
GDateTime *dt;
gchar *date;
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);
GDateTime *dt;
gchar *date;
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 @@
if (!protocol)
return NULL;
- 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 @@
if (!protocol)
return NULL;
- 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
+ * 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/>.
*/
+
#include "protocol.h"
-static GObjectClass *parent_class;
+#include "enums.h"
-/**************************************************************************
- * Protocol Object API
- **************************************************************************/
-const char *
-purple_protocol_get_id(const PurpleProtocol *protocol)
-{
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+enum {
+ PROP_0,
+ PROP_ID,
+ PROP_NAME,
+ PROP_OPTIONS,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+typedef struct {
+ gchar *id;
+ gchar *name;
- return protocol->id;
-}
+ PurpleProtocolOptions options;
+} PurpleProtocolPrivate;
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleProtocol, purple_protocol,
+ G_TYPE_OBJECT)
-const char *
-purple_protocol_get_name(const PurpleProtocol *protocol)
-{
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_protocol_set_id(PurpleProtocol *protocol, const gchar *id) {
+ PurpleProtocolPrivate *priv = NULL;
- return protocol->name;
+ priv = purple_protocol_get_instance_private(protocol);
+ g_free(priv->id);
+ priv->id = g_strdup(id);
+
+ g_object_notify_by_pspec(G_OBJECT(protocol), properties[PROP_ID]);
}
-PurpleProtocolOptions
-purple_protocol_get_options(const PurpleProtocol *protocol)
-{
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), 0);
-
- return protocol->options;
-}
-
-GList *
-purple_protocol_get_user_splits(const PurpleProtocol *protocol)
-{
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
-
- return protocol->user_splits;
-}
+static void
+purple_protocol_set_name(PurpleProtocol *protocol, const gchar *name) {
+ PurpleProtocolPrivate *priv = NULL;
-GList *
-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);
+ g_free(priv->name);
+ priv->name = g_strdup(name);
-PurpleBuddyIconSpec *
-purple_protocol_get_icon_spec(const PurpleProtocol *protocol)
-{
- g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
-
- return protocol->icon_spec;
-}
-
-PurpleWhiteboardOps *
-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]);
}
static void
-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 stuff
- **************************************************************************/
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
static void
-purple_protocol_init(GTypeInstance *instance, gpointer klass)
+purple_protocol_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
{
+ PurpleProtocol *protocol = PURPLE_PROTOCOL(obj);
+
+ switch(param_id) {
+ case PROP_ID:
+ g_value_set_string(value, purple_protocol_get_id(protocol));
+ break;
+ case PROP_NAME:
+ g_value_set_string(value, purple_protocol_get_name(protocol));
+ break;
+ case PROP_OPTIONS:
+ g_value_set_flags(value, purple_protocol_get_options(protocol));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
}
static void
-purple_protocol_finalize(GObject *object)
+purple_protocol_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
{
+ PurpleProtocol *protocol = PURPLE_PROTOCOL(obj);
+
+ switch(param_id) {
+ case PROP_ID:
+ purple_protocol_set_id(protocol, g_value_get_string(value));
+ break;
+ case PROP_NAME:
+ purple_protocol_set_name(protocol, g_value_get_string(value));
+ break;
+ case PROP_OPTIONS:
+ purple_protocol_set_options(protocol, g_value_get_flags(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_protocol_init(PurpleProtocol *protocol) {
+}
+
+static void
+purple_protocol_finalize(GObject *object) {
PurpleProtocol *protocol = PURPLE_PROTOCOL(object);
+ PurpleProtocolPrivate *priv = NULL;
GList *accounts, *l;
+ 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
+ * they should?
+ */
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))
continue;
- 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);
}
g_list_free(accounts);
+ /* 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);
}
static void
-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;
+
+ /**
+ * PurpleProtocol::id:
+ *
+ * The identifier for the protocol.
+ */
+ properties[PROP_ID] = g_param_spec_string(
+ "id", "id",
+ "The identifier for the protocol",
+ NULL,
+ 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(
+ "name", "name",
+ "The name of the protocol to show in the user interface",
+ NULL,
+ 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(
+ "options", "options",
+ "The options for the protocol",
+ PURPLE_TYPE_PROTOCOL_OPTIONS,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+const gchar *
+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);
+
+ return priv->id;
}
-GType
-purple_protocol_get_type(void)
-{
- static GType type = 0;
+const gchar *
+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);
+
+ return priv->name;
+}
+
+PurpleProtocolOptions
+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);
+
+ return priv->options;
+}
- type = g_type_register_static(G_TYPE_OBJECT, "PurpleProtocol",
- &info, G_TYPE_FLAG_ABSTRACT);
+GList *
+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);
}
- return type;
+ return NULL;
}
-/**************************************************************************
- * Protocol Class API
- **************************************************************************/
-#define DEFINE_PROTOCOL_FUNC(protocol,funcname,...) \
- PurpleProtocolClass *klass = PURPLE_PROTOCOL_GET_CLASS(protocol); \
- g_return_if_fail(klass != NULL); \
- if (klass->funcname) \
- klass->funcname(__VA_ARGS__);
+GList *
+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);
+ }
+
+ return NULL;
+}
+
+PurpleBuddyIconSpec *
+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); \
- if (klass->funcname) \
- return klass->funcname(__VA_ARGS__); \
- else \
- return defaultreturn;
+ klass = PURPLE_PROTOCOL_GET_CLASS(protocol);
+ if(klass != NULL && klass->get_buddy_icon_spec != NULL) {
+ return klass->get_buddy_icon_spec(protocol);
+ }
+
+ return NULL;
+}
-void
-purple_protocol_class_login(PurpleProtocol *protocol, PurpleAccount *account)
-{
- DEFINE_PROTOCOL_FUNC(protocol, login, account);
+PurpleWhiteboardOps *
+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);
+ }
+
+ return NULL;
}
void
-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) {
+ klass->login(account);
+ }
+}
+
+void
+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) {
+ klass->close(gc);
+ }
}
GList *
-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);
+ }
+
+ return NULL;
}
-const char *
-purple_protocol_class_list_icon(PurpleProtocol *protocol,
- PurpleAccount *account, PurpleBuddy *buddy)
+const gchar *
+purple_protocol_get_list_icon(PurpleProtocol *protocol, PurpleAccount *account,
+ PurpleBuddy *buddy)
{
- 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);
+ }
+
+ return NULL;
+}
--- 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.h>
+#include <glib-object.h>
+
/**
* SECTION:protocol
* @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,
+ GObject)
#include "account.h"
#include "buddyicon.h"
@@ -67,75 +64,51 @@
/**
* PurpleProtocol:
- * @id: Protocol ID
- * @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.
*/
-struct _PurpleProtocol
-{
- GObject gparent;
-
- /*< public >*/
- const char *id;
- const char *name;
-
- PurpleProtocolOptions options;
-
- GList *user_splits;
- GList *account_options;
-
- PurpleBuddyIconSpec *icon_spec;
- PurpleWhiteboardOps *whiteboard_ops;
-
- /*< private >*/
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
-};
/**
* PurpleProtocolClass:
- * @login: Log in to the server.
- * @close: Close connection with the server.
+ * @get_user_splits: Returns a list of all #PurpleAccountUserSplit's that the
+ * procotol provides.
+ * @get_account_options: Returns a list of all #PurpleAccountOption's for the
+ * protocol.
+ * @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.
+ *
+ * Since: 3.0.0
*/
-/* 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);
/*< private >*/
- void (*_purple_reserved1)(void);
- void (*_purple_reserved2)(void);
- void (*_purple_reserved3)(void);
- void (*_purple_reserved4)(void);
+ gpointer reserved[4];
};
/**
@@ -153,102 +126,144 @@
G_BEGIN_DECLS
-/**************************************************************************/
-/* 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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
*/
-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.
+ *
+ * Since: 3.0.0
+ */
+void purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account);
+
+/**
+ * purple_protocol_close:
+ * @protocol: The #PurpleProtocol instance.
+ * @connection: The #PurpleConnection to close.
+ *
+ * Closes @connection using @protocol.
+ *
+ * Since: 3.0.0
+ */
+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.
+ *
+ * Since: 3.0.0
+ */
+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
+ * @protocol.
+ *
+ * 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.
+ *
+ * Since: 3.0.0
+ */
+const gchar *purple_protocol_get_list_icon(PurpleProtocol *protocol, PurpleAccount *account, PurpleBuddy *buddy);
G_END_DECLS
--- 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;
}
+static GList *
+bonjour_protocol_get_account_options(PurpleProtocol *protocol) {
+ PurpleAccountOption *option;
+ GList *opts = NULL;
+
+ /* Creating the options for the protocol */
+ option = purple_account_option_int_new(_("Local Port"), "port",
+ BONJOUR_DEFAULT_PORT);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_string_new(_("First name"), "first",
+ default_firstname);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_string_new(_("Last name"), "last",
+ default_lastname);
+ 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);
+
+ return opts;
+}
+
+static PurpleBuddyIconSpec *
+bonjour_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) {
+ return purple_buddy_icon_spec_new("png,gif,jpeg",
+ 0, 0, 96, 96, 65535,
+ PURPLE_ICON_SCALE_DISPLAY);
+}
+
static int
bonjour_send_im(PurpleProtocolIM *im, PurpleConnection *connection, PurpleMessage *msg)
{
@@ -639,34 +676,6 @@
static void
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",
- 0, 0, 96, 96, 65535,
- 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);
}
static void
@@ -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;
}
static void
@@ -734,6 +746,16 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
bonjour_protocol_xfer_iface_init));
+static PurpleProtocol *
+bonjour_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ BONJOUR_TYPE_PROTOCOL,
+ "id", "prpl-bonjour",
+ "name", "Bonjour",
+ "options", OPT_PROTO_NO_PASSWORD,
+ NULL));
+}
+
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 @@
g_slist_free(select);
}
+static GList *
+fb_get_account_options(PurpleProtocol *protocol) {
+ GList *opts = NULL;
+ PurpleAccountOption *opt;
+
+ opt = purple_account_option_int_new(_("Buddy list sync interval"),
+ "sync-interval", 5);
+ opts = g_list_prepend(opts, opt);
+
+ opt = purple_account_option_bool_new(_("Mark messages as read on focus"),
+ "mark-read", TRUE);
+ 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"),
+ "show-self", TRUE);
+ opts = g_list_prepend(opts, opt);
+
+ opt = purple_account_option_bool_new(_("Show unread messages"),
+ "show-unread", TRUE);
+ opts = g_list_prepend(opts, opt);
+
+ opt = purple_account_option_bool_new(_("Open new group chats with "
+ "incoming messages"),
+ "group-chat-open", TRUE);
+ opts = g_list_prepend(opts, opt);
+
+ return g_list_reverse(opts);
+}
+
static void
fb_login(PurpleAccount *acct)
{
@@ -1524,41 +1557,7 @@
}
static void
-facebook_protocol_init(FacebookProtocol *self)
-{
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- GList *opts = NULL;
- 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"),
- "sync-interval", 5);
- opts = g_list_prepend(opts, opt);
-
- opt = purple_account_option_bool_new(_("Mark messages as read on focus"),
- "mark-read", TRUE);
- 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"),
- "show-self", TRUE);
- opts = g_list_prepend(opts, opt);
-
- opt = purple_account_option_bool_new(_("Show unread messages"),
- "show-unread", TRUE);
- opts = g_list_prepend(opts, opt);
-
- opt = purple_account_option_bool_new(_("Open new group chats with "
- "incoming messages"),
- "group-chat-open", TRUE);
- opts = g_list_prepend(opts, opt);
- protocol->account_options = g_list_reverse(opts);
+facebook_protocol_init(FacebookProtocol *self) {
}
static void
@@ -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"),
NULL);
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"),
NULL);
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,
+ "id", FB_PROTOCOL_ID,
+ "name", "Facebook",
+ "options", OPT_PROTO_CHAT_TOPIC,
+ NULL);
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 @@
return "gadu-gadu";
}
+static PurpleBuddyIconSpec *
+ggp_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) {
+ return purple_buddy_icon_spec_new("png",
+ 1, 1, 200, 200, 0,
+ PURPLE_ICON_SCALE_DISPLAY |
+ PURPLE_ICON_SCALE_SEND);
+}
+
+static GList *
+ggp_protocol_get_account_options(PurpleProtocol *protocol) {
+ PurpleAccountOption *option = NULL;
+ PurpleKeyValuePair *kvp = NULL;
+ GList *encryption_options = NULL;
+ GList *protocol_version = NULL;
+ GList *opts = 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"),
+ "opportunistic_tls");
+ 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"),
+ "protocol_version",
+ 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);
+
+ return opts;
+}
+
static const char *
ggp_normalize(PurpleProtocolClient *client, PurpleAccount *account,
const char *who)
@@ -1026,52 +1081,6 @@
static void
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",
- 1, 1, 200, 200, 0,
- PURPLE_ICON_SCALE_DISPLAY |
- PURPLE_ICON_SCALE_SEND);
-
- option = purple_account_option_string_new(_("GG server"),
- "gg_server", "");
- protocol->account_options = g_list_append(protocol->account_options,
- option);
- 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"),
- "opportunistic_tls");
- 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,
- option);
-
- 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);
-
- option = purple_account_option_bool_new(_("Show links from strangers"),
- "show_links_from_strangers", 1);
- protocol->account_options = g_list_append(protocol->account_options,
- option);
}
static void
@@ -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;
}
static void
@@ -1184,6 +1196,15 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
ggp_protocol_xfer_iface_init));
+static PurpleProtocol *
+ggp_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ GGP_TYPE_PROTOCOL,
+ "id", "prpl-gg",
+ "name", "Gadu-Gadu",
+ NULL));
+}
+
static gchar *
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_libgaduw_setup();
ggp_resolver_purple_setup();
- ggp_servconn_setup(ggp_server_option);
+ ggp_servconn_setup(NULL);
ggp_html_setup();
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 @@
return "irc";
}
+static GList *
+irc_protocol_get_account_options(PurpleProtocol *protocol) {
+ PurpleAccountOption *option;
+ GList *opts = NULL;
+
+ option = purple_account_option_int_new(_("Port"), "port",
+ IRC_DEFAULT_PORT);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_string_new(_("Encodings"), "encoding",
+ IRC_DEFAULT_CHARSET);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_bool_new(_("Auto-detect incoming UTF-8"),
+ "autodetect_utf8",
+ 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",
+ IRC_DEFAULT_QUIT);
+ opts = g_list_append(opts, option);
+ */
+
+ option = purple_account_option_bool_new(_("Use SSL"), "ssl", FALSE);
+ opts = g_list_append(opts, option);
+
+#ifdef HAVE_CYRUS_SASL
+ option = purple_account_option_bool_new(_("Authenticate with SASL"),
+ "sasl", FALSE);
+ 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);
+#endif
+
+ return opts;
+}
+
+static GList *
+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)
{
PurpleStatusType *type;
@@ -972,50 +1029,6 @@
static void
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);
-
-#ifdef HAVE_CYRUS_SASL
- 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);
-#endif
}
static void
@@ -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;
}
static void
@@ -1107,6 +1123,17 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
irc_protocol_xfer_iface_init));
+static PurpleProtocol *
+irc_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ IRC_TYPE_PROTOCOL,
+ "id", "prpl-irc",
+ "name", "IRC",
+ "options", OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL |
+ OPT_PROTO_SLASH_COMMANDS_NATIVE,
+ NULL));
+}
+
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);
if (!acct)
return FALSE;
@@ -4076,24 +4076,16 @@
jabber_do_uninit();
}
+static PurpleBuddyIconSpec *
+jabber_protocol_get_buddy_icon_spec(PurpleProtocol *protocol) {
+ return purple_buddy_icon_spec_new("png",
+ 32, 32, 96, 96, 0,
+ PURPLE_ICON_SCALE_SEND |
+ PURPLE_ICON_SCALE_DISPLAY);
+}
+
static void
-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_MAIL_CHECK |
-#ifdef HAVE_CYRUS_SASL
- OPT_PROTO_PASSWORD_OPTIONAL |
-#endif
- OPT_PROTO_SLASH_COMMANDS_NATIVE;
-
- protocol->icon_spec = purple_buddy_icon_spec_new("png",
- 32, 32, 96, 96, 0,
- PURPLE_ICON_SCALE_SEND |
- PURPLE_ICON_SCALE_DISPLAY);
+jabber_protocol_init(JabberProtocol *self) {
}
static void
@@ -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 <config.h>
+
#include <glib/gi18n-lib.h>
#include <purple.h>
#include "xmpp.h"
-static void
-xmpp_protocol_init(XMPPProtocol *self)
-{
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountUserSplit *split;
+static GList *
+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"),
+ "opportunistic_tls");
+ 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);
-#undef ADD_VALUE
-
- option = purple_account_option_list_new(_("Connection security"), "connection_security", encryption_values);
- protocol->account_options = g_list_append(protocol->account_options,
- option);
+ /* build all the options */
+ option = purple_account_option_list_new(_("Connection security"),
+ "connection_security",
+ encryption_values);
+ 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);
+ 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,
- option);
+ 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,
- option);
+ "connect_server", NULL);
+ opts = g_list_append(opts, option);
option = purple_account_option_string_new(_("File transfer proxies"),
- "ft_proxies", NULL);
- protocol->account_options = g_list_append(protocol->account_options,
- option);
+ "ft_proxies", NULL);
+ opts = g_list_append(opts, option);
- option = purple_account_option_string_new(_("BOSH URL"),
- "bosh_url", NULL);
- protocol->account_options = g_list_append(protocol->account_options,
- option);
+ 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
* later on
*/
option = purple_account_option_bool_new(_("Show Custom Smileys"),
- "custom_smileys", TRUE);
- protocol->account_options = g_list_append(protocol->account_options,
- option);
+ "custom_smileys", TRUE);
+ opts = g_list_append(opts, option);
+
+ return opts;
+}
+
+static GList *
+xmpp_protocol_get_user_splits(PurpleProtocol *protocol) {
+ GList *splits = NULL;
+ PurpleAccountUserSplit *split;
+ /* 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);
+ 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);
+
+ return splits;
+}
+
+static void
+xmpp_protocol_init(XMPPProtocol *self) {
purple_prefs_remove("/plugins/prpl/jabber");
}
static void
-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;
}
static void
@@ -114,3 +126,23 @@
{
xmpp_protocol_register_type(G_TYPE_MODULE(plugin));
}
+
+PurpleProtocol *
+xmpp_protocol_new(void) {
+ PurpleProtocolOptions options;
+
+ options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME |
+ OPT_PROTO_MAIL_CHECK | OPT_PROTO_SLASH_COMMANDS_NATIVE;
+
+#ifdef HAVE_CYRUS_SASL
+ options |= OPT_PROTO_PASSWORD_OPTIONAL;
+#endif
+
+ return PURPLE_PROTOCOL(g_object_new(
+ XMPP_TYPE_PROTOCOL,
+ "id", XMPP_PROTOCOL_ID,
+ "name", "XMPP",
+ "options", options,
+ NULL
+ ));
+}
\ 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 @@
#include "jabber.h"
+#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 @@
G_GNUC_INTERNAL
void xmpp_protocol_register(PurplePlugin *plugin);
+G_GNUC_INTERNAL
+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 @@
return "novell";
}
+static GList *
+novell_protocol_get_account_options(PurpleProtocol *protocol) {
+ PurpleAccountOption *option;
+ GList *opts = NULL;
+
+ option = purple_account_option_string_new(_("Server address"), "server",
+ NULL);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_int_new(_("Server port"), "port",
+ DEFAULT_PORT);
+ opts = g_list_append(opts, option);
+
+ return opts;
+}
+
static void
novell_tooltip_text(PurpleProtocolClient *client, PurpleBuddy *buddy,
PurpleNotifyUserInfo *user_info, gboolean full)
@@ -3507,19 +3523,6 @@
static void
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);
}
static void
@@ -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;
}
static void
@@ -3607,6 +3612,15 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_PRIVACY,
novell_protocol_privacy_iface_init));
+static PurpleProtocol *
+novell_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ NOVELL_TYPE_PROTOCOL,
+ "id", "prpl-novell",
+ "name", "GroupWise",
+ NULL));
+}
+
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 @@
return "null";
}
+static GList *
+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 */
+ 0, /* min_width */
+ 0, /* min_height */
+ 128, /* max_width */
+ 128, /* max_height */
+ 10000, /* max_filesize */
+ PURPLE_ICON_SCALE_DISPLAY /* scale_rules */
+ );
+}
+
+static GList *
+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);
+}
+
static char *
null_status_text(PurpleProtocolClient *client, PurpleBuddy *buddy) {
purple_debug_info("nullprpl", "getting %s's status text for %s\n",
@@ -1048,36 +1085,6 @@
static void
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 */
- 0, /* min_width */
- 0, /* min_height */
- 128, /* max_width */
- 128, /* max_height */
- 10000, /* max_filesize */
- PURPLE_ICON_SCALE_DISPLAY /* scale_rules */
- );
-
- /* see accountopt.h for information about user splits and protocol
- * options */
- 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;
}
static void
@@ -1199,6 +1210,16 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_ROOMLIST,
null_protocol_roomlist_iface_init));
+static PurpleProtocol *
+null_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ NULL_TYPE_PROTOCOL,
+ "id", "prpl-null",
+ "name", "Null - Testing Protocol",
+ "options", OPT_PROTO_NO_PASSWORD | OPT_PROTO_CHAT_TOPIC,
+ NULL));
+}
+
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 @@
return "meanwhile";
}
+static GList *
+mw_protocol_get_account_options(PurpleProtocol *protocol) {
+ PurpleAccountOption *opt;
+ GList *opts = NULL;
+
+ /* 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. */
+ gboolean b = FALSE;
+ 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);
+
+ return opts;
+}
+
+static GList *
+mw_protocol_get_user_splits(PurpleProtocol *protocol) {
+ PurpleAccountUserSplit *split;
+ GList *splits = NULL;
+
+ /* set up account ID as user:server */
+ split = purple_account_user_split_new(_("Server"),
+ MW_PLUGIN_DEFAULT_HOST, ':');
+ splits = g_list_append(splits, split);
+
+ return splits;
+}
static const char *
mw_protocol_list_emblem(PurpleProtocolClient *client, PurpleBuddy *b) {
@@ -5209,53 +5252,14 @@
static void
mw_protocol_init(mwProtocol *self)
{
- PurpleProtocol *protocol = PURPLE_PROTOCOL(self);
- PurpleAccountUserSplit *split;
- PurpleAccountOption *opt;
- GList *l = NULL;
-
- 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,
BLIST_CHOICE_DEFAULT);
- /* 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. */
- gboolean b = FALSE;
- 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;
- l = NULL;
}
static void
@@ -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;
}
static void
@@ -5368,6 +5375,15 @@
G_IMPLEMENT_INTERFACE_DYNAMIC(PURPLE_TYPE_PROTOCOL_XFER,
mw_protocol_xfer_iface_init));
+static PurpleProtocol *
+mw_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ MW_TYPE_PROTOCOL,
+ "id", PROTOCOL_ID,
+ "name", PROTOCOL_NAME,
+ NULL));
+}
+
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 @@
return "zephyr";
}
+static GList *
+zephyr_protocol_get_account_options(PurpleProtocol *protocol) {
+ PurpleAccountOption *option;
+ GList *opts = NULL;
+ 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",
+ "/usr/bin/tzc -e %s");
+ 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"),
+ "write_zsubs", FALSE);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_bool_new(_("Import from .anyone"),
+ "read_anyone", TRUE);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_bool_new(_("Import from .zephyr.subs"),
+ "read_zsubs", TRUE);
+ 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",
+ tmp);
+ opts = g_list_append(opts, option);
+
+ option = purple_account_option_string_new(_("Encoding"), "encoding",
+ ZEPHYR_FALLBACK_CHARSET);
+ opts = g_list_append(opts, option);
+
+ return opts;
+}
+
static unsigned int
zephyr_send_typing(G_GNUC_UNUSED PurpleProtocolIM *im, PurpleConnection *gc, const char *who, PurpleIMTypingState state)
{
@@ -1576,41 +1619,6 @@
static void
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",
- tmp);
- 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));
+static PurpleProtocol *
+zephyr_protocol_new(void) {
+ return PURPLE_PROTOCOL(g_object_new(
+ ZEPHYR_TYPE_PROTOCOL,
+ "id", "prpl-zephyr",
+ "name", "Zephyr",
+ "options", OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD,
+ NULL));
+}
+
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 @@
static void
test_purple_protocol_attention_init(TestPurpleProtocolAttention *prplattn) {
- PurpleProtocol *prpl = PURPLE_PROTOCOL(prplattn);
-
- prpl->id = "prpl-attention";
}
static void
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",
+ NULL);
+}
+
/******************************************************************************
* Tests
*****************************************************************************/
static void
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);
gboolean actual = FALSE;
--- 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 @@
static void
test_purple_protocol_xfer_init(TestPurpleProtocolXfer *prplxfer) {
- PurpleProtocol *prpl = PURPLE_PROTOCOL(prplxfer);
-
- prpl->id = "prpl-xfer";
}
static void
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(),
+ "id", "prpl-xfer",
+ NULL);
+}
+
/******************************************************************************
* Tests
*****************************************************************************/
static void
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);
gboolean actual = FALSE;
@@ -112,7 +117,7 @@
xfer->can_send = FALSE;
actual = purple_protocol_xfer_can_receive(
PURPLE_PROTOCOL_XFER(xfer),
- c,
+ c,
"foo"
);
g_assert_false(actual);
--- 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 @@
pixbuf = scale;
}
+ purple_buddy_icon_spec_free(icon_spec);
+
if (pixbuf == NULL)
{
/* 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);
+
if (username != NULL)
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;
PurpleAccount *account;
GtkWidget *vbox, *check, *entry, *combo;
- GList *list, *node;
+ GList *list, *node, *opts;
gint i, idx, int_value;
GtkListStore *model;
GtkTreeIter iter;
@@ -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) {
return;
+ }
+
+ opts = purple_protocol_get_account_options(dialog->protocol);
+ if(opts == NULL) {
+ return;
+ }
account = dialog->account;
@@ -801,7 +813,7 @@
gtk_label_new_with_mnemonic(_("Ad_vanced")), 1);
gtk_widget_show(vbox);
- 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);
}
static GtkWidget *
@@ -1396,6 +1409,8 @@
}
}
+ purple_buddy_icon_spec_free(icon_spec);
+
/* Remember Password */
remember = gtk_toggle_button_get_active(
@@ -2167,6 +2182,8 @@
}
}
+ purple_buddy_icon_spec_free(icon_spec);
+
if (img != NULL) {
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 @@
}
protocol =
- 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 @@
if (protocol)
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,
+ &scale_height);
+ }
+
+ purple_buddy_icon_spec_free(icon_spec);
if (scaled || scale_height > 200 || scale_width > 200) {
GdkPixbuf *tmpbuf;
--- 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 @@
char *filename = NULL;
GdkPixbuf *pixbuf;
- protoname = purple_protocol_class_list_icon(protocol, account, NULL);
+ protoname = purple_protocol_get_list_icon(protocol, account, NULL);
if (protoname == NULL)
return 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))
break;
@@ -1523,11 +1523,18 @@
gchar *tmp;
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);
+
+ return NULL;
+ }
format = gdk_pixbuf_get_file_info(path, &orig_width, &orig_height);
if (format == NULL) {
purple_debug_warning("buddyicon", "Could not get file info of %s\n", path);
+
+ purple_buddy_icon_spec_free(spec);
+
return NULL;
}
@@ -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);
return NULL;
}
@@ -1554,6 +1562,7 @@
if (len)
*len = length;
g_strfreev(protocol_formats);
+ purple_buddy_icon_spec_free(spec);
return contents;
}
@@ -1570,6 +1579,7 @@
"conversion: %s\n", path, error->message);
g_error_free(error);
g_strfreev(protocol_formats);
+ purple_buddy_icon_spec_free(spec);
return NULL;
}
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);
return contents;
}
@@ -1672,6 +1683,8 @@
purple_notify_error(NULL, _("Icon Error"), _("Could not set icon"), tmp, NULL);
g_free(tmp);
+ purple_buddy_icon_spec_free(spec);
+
return NULL;
}