summaryrefslogtreecommitdiff
path: root/libpurple/buddy.c
diff options
context:
space:
mode:
authorGary Kramlich <grim@reaperworld.com>2021-02-03 18:49:38 -0600
committerGary Kramlich <grim@reaperworld.com>2021-02-03 18:49:38 -0600
commitbc38c82dcc17ca6e074b350f1b6d6ffa46cc9185 (patch)
treed058c2b469baad3adfb4323697eb0def52dc827f /libpurple/buddy.c
parent9423b663f3d84c08407e471289c08e03f840953f (diff)
downloadpidgin-bc38c82dcc17ca6e074b350f1b6d6ffa46cc9185.tar.gz
Update buddy.c to more closely match our current gobject structure.
Testing Done: Compiled and ran pidgin locally. Reviewed at https://reviews.imfreedom.org/r/473/
Diffstat (limited to 'libpurple/buddy.c')
-rw-r--r--libpurple/buddy.c770
1 files changed, 384 insertions, 386 deletions
diff --git a/libpurple/buddy.c b/libpurple/buddy.c
index d86e553db0..a3de7de087 100644
--- a/libpurple/buddy.c
+++ b/libpurple/buddy.c
@@ -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,32 +17,27 @@
* 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 "internal.h"
#include "purplebuddypresence.h"
#include "purpleprotocolclient.h"
#include "util.h"
-typedef struct _PurpleBuddyPrivate PurpleBuddyPrivate;
-
-struct _PurpleBuddyPrivate {
- char *name; /* The name of the buddy. */
- char *local_alias; /* The user-set alias of the buddy */
- char *server_alias; /* The server-specified alias of the buddy.
- (i.e. MSN "Friendly Names") */
- void *proto_data; /* This allows the protocol to associate
- whatever data it wants with a buddy. */
- PurpleBuddyIcon *icon; /* The buddy icon. */
- PurpleAccount *account; /* the account this buddy belongs to */
- PurplePresence *presence; /* Presense information of the buddy */
- PurpleMediaCaps media_caps; /* The media capabilities of the buddy. */
-
- gboolean is_constructed; /* Indicates if the buddy has finished
- being constructed. */
-};
+typedef struct {
+ gchar *name;
+ gchar *local_alias;
+ gchar *server_alias;
+
+ gpointer proto_data;
+
+ PurpleBuddyIcon *icon;
+ PurpleAccount *account;
+ PurplePresence *presence;
+
+ PurpleMediaCaps media_caps;
+} PurpleBuddyPrivate;
enum {
PROP_0,
@@ -52,37 +48,233 @@ enum {
PROP_ACCOUNT,
PROP_PRESENCE,
PROP_MEDIA_CAPS,
- PROP_LAST
+ N_PROPERTIES
};
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+G_DEFINE_TYPE_WITH_PRIVATE(PurpleBuddy, purple_buddy, PURPLE_TYPE_BLIST_NODE)
+
/******************************************************************************
- * Globals
+ * Helpers
*****************************************************************************/
-static GParamSpec *properties[PROP_LAST];
+static void
+purple_buddy_set_account(PurpleBuddy *buddy, PurpleAccount *account) {
+ PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(buddy);
-G_DEFINE_TYPE_WITH_PRIVATE(PurpleBuddy, purple_buddy, PURPLE_TYPE_BLIST_NODE)
+ if(g_set_object(&priv->account, account)) {
+ g_object_notify_by_pspec(G_OBJECT(buddy), properties[PROP_ACCOUNT]);
+ }
+}
/******************************************************************************
- * API
+ * GObject Implementation
*****************************************************************************/
-void
-purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon)
+static void
+purple_buddy_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(obj);
+
+ switch (param_id) {
+ case PROP_NAME:
+ purple_buddy_set_name(buddy, g_value_get_string(value));
+ break;
+ case PROP_LOCAL_ALIAS:
+ purple_buddy_set_local_alias(buddy, g_value_get_string(value));
+ break;
+ case PROP_SERVER_ALIAS:
+ purple_buddy_set_server_alias(buddy, g_value_get_string(value));
+ break;
+ case PROP_ICON:
+ purple_buddy_set_icon(buddy, g_value_get_pointer(value));
+ break;
+ case PROP_ACCOUNT:
+ purple_buddy_set_account(buddy,
+ PURPLE_ACCOUNT(g_value_get_object(value)));
+ break;
+ case PROP_MEDIA_CAPS:
+ purple_buddy_set_media_caps(buddy, g_value_get_enum(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_buddy_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleBuddy *buddy = PURPLE_BUDDY(obj);
+
+ switch (param_id) {
+ case PROP_NAME:
+ g_value_set_string(value, purple_buddy_get_name(buddy));
+ break;
+ case PROP_LOCAL_ALIAS:
+ g_value_set_string(value, purple_buddy_get_local_alias(buddy));
+ break;
+ case PROP_SERVER_ALIAS:
+ g_value_set_string(value, purple_buddy_get_server_alias(buddy));
+ break;
+ case PROP_ICON:
+ g_value_set_pointer(value, purple_buddy_get_icon(buddy));
+ break;
+ case PROP_ACCOUNT:
+ g_value_set_object(value, purple_buddy_get_account(buddy));
+ break;
+ case PROP_PRESENCE:
+ g_value_set_object(value, purple_buddy_get_presence(buddy));
+ break;
+ case PROP_MEDIA_CAPS:
+ g_value_set_enum(value, purple_buddy_get_media_caps(buddy));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_buddy_init(PurpleBuddy *buddy) {
+}
+
+static void
+purple_buddy_constructed(GObject *object) {
+ PurpleBuddy *buddy = PURPLE_BUDDY(object);
+ PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(buddy);
+
+ G_OBJECT_CLASS(purple_buddy_parent_class)->constructed(object);
+
+ priv->presence = PURPLE_PRESENCE(purple_buddy_presence_new(buddy));
+ purple_presence_set_status_active(priv->presence, "offline", TRUE);
+
+ purple_blist_new_node(purple_blist_get_default(),
+ PURPLE_BLIST_NODE(buddy));
+}
+
+static void
+purple_buddy_dispose(GObject *object) {
+ PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(PURPLE_BUDDY(object));
+
+ g_clear_pointer(&priv->icon, purple_buddy_icon_unref);
+ g_clear_object(&priv->presence);
+
+ G_OBJECT_CLASS(purple_buddy_parent_class)->dispose(object);
+}
+
+static void
+purple_buddy_finalize(GObject *object) {
+ PurpleBuddy *buddy = PURPLE_BUDDY(object);
+ PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(buddy);
+ PurpleProtocol *protocol;
+
+ /*
+ * Tell the owner protocol that we're about to free the buddy so it
+ * can free proto_data
+ */
+ protocol = purple_protocols_find(purple_account_get_protocol_id(priv->account));
+ if(protocol) {
+ purple_protocol_client_buddy_free(PURPLE_PROTOCOL_CLIENT(protocol),
+ buddy);
+ }
+
+ g_free(priv->name);
+ g_free(priv->local_alias);
+ g_free(priv->server_alias);
+
+ G_OBJECT_CLASS(purple_buddy_parent_class)->finalize(object);
+}
+
+static void purple_buddy_class_init(PurpleBuddyClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->constructed = purple_buddy_constructed;
+ obj_class->dispose = purple_buddy_dispose;
+ obj_class->finalize = purple_buddy_finalize;
+ obj_class->get_property = purple_buddy_get_property;
+ obj_class->set_property = purple_buddy_set_property;
+
+ properties[PROP_NAME] = g_param_spec_string(
+ "name", "Name",
+ "The name of the buddy.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_LOCAL_ALIAS] = g_param_spec_string(
+ "local-alias", "Local alias",
+ "Local alias of thee buddy.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_SERVER_ALIAS] = g_param_spec_string(
+ "server-alias", "Server alias",
+ "Server-side alias of the buddy.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_ICON] = g_param_spec_pointer(
+ "icon", "Buddy icon",
+ "The icon for the buddy.",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_ACCOUNT] = g_param_spec_object(
+ "account", "Account",
+ "The account for the buddy.",
+ PURPLE_TYPE_ACCOUNT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_PRESENCE] = g_param_spec_object(
+ "presence", "Presence",
+ "The status information for the buddy.",
+ PURPLE_TYPE_PRESENCE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_MEDIA_CAPS] = g_param_spec_enum(
+ "media-caps", "Media capabilities",
+ "The media capabilities of the buddy.",
+ PURPLE_MEDIA_TYPE_CAPS, PURPLE_MEDIA_CAPS_NONE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleBuddy *
+purple_buddy_new(PurpleAccount *account, const gchar *name, const gchar *alias)
{
+ g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ return g_object_new(
+ PURPLE_TYPE_BUDDY,
+ "account", account,
+ "name", name,
+ "local-alias", alias,
+ NULL);
+}
+
+void
+purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon) {
PurpleBuddyPrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
priv = purple_buddy_get_instance_private(buddy);
+ if(priv->icon == icon) {
+ return;
+ }
- if (priv->icon != icon)
- {
- purple_buddy_icon_unref(priv->icon);
- priv->icon = (icon != NULL ? purple_buddy_icon_ref(icon) : NULL);
-
- g_object_notify_by_pspec(G_OBJECT(buddy),
- properties[PROP_ICON]);
+ g_clear_pointer(&priv->icon, purple_buddy_icon_unref);
+ if(icon != NULL) {
+ priv->icon = purple_buddy_icon_ref(icon);
}
+ g_object_notify_by_pspec(G_OBJECT(buddy), properties[PROP_ICON]);
+
purple_signal_emit(purple_blist_get_handle(), "buddy-icon-changed", buddy);
purple_blist_update_node(purple_blist_get_default(),
@@ -90,105 +282,104 @@ purple_buddy_set_icon(PurpleBuddy *buddy, PurpleBuddyIcon *icon)
}
PurpleBuddyIcon *
-purple_buddy_get_icon(PurpleBuddy *buddy)
-{
+purple_buddy_get_icon(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->icon;
}
PurpleAccount *
-purple_buddy_get_account(PurpleBuddy *buddy)
-{
+purple_buddy_get_account(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->account;
}
void
-purple_buddy_set_name(PurpleBuddy *buddy, const char *name)
-{
+purple_buddy_set_name(PurpleBuddy *buddy, const gchar *name) {
+ PurpleBuddyList *blist = NULL;
PurpleBuddyPrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
priv = purple_buddy_get_instance_private(buddy);
- purple_blist_update_buddies_cache(buddy, name);
+ if(priv->name != NULL) {
+ purple_blist_update_buddies_cache(buddy, name);
+ }
g_free(priv->name);
priv->name = purple_utf8_strip_unprintables(name);
g_object_notify_by_pspec(G_OBJECT(buddy), properties[PROP_NAME]);
- purple_blist_save_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
- purple_blist_update_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
+ blist = purple_blist_get_default();
+ purple_blist_save_node(blist, PURPLE_BLIST_NODE(buddy));
+ purple_blist_update_node(blist, PURPLE_BLIST_NODE(buddy));
}
-const char *
-purple_buddy_get_name(PurpleBuddy *buddy)
-{
+const gchar *
+purple_buddy_get_name(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->name;
}
gpointer
-purple_buddy_get_protocol_data(PurpleBuddy *buddy)
-{
+purple_buddy_get_protocol_data(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->proto_data;
}
void
-purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data)
-{
+purple_buddy_set_protocol_data(PurpleBuddy *buddy, gpointer data) {
PurpleBuddyPrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
priv = purple_buddy_get_instance_private(buddy);
+
priv->proto_data = data;
}
-const char *purple_buddy_get_alias_only(PurpleBuddy *buddy)
-{
+const gchar *
+purple_buddy_get_alias_only(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
- if ((priv->local_alias != NULL) && (*priv->local_alias != '\0')) {
+ if((priv->local_alias != NULL) && (*priv->local_alias != '\0')) {
return priv->local_alias;
- } else if ((priv->server_alias != NULL) &&
- (*priv->server_alias != '\0')) {
-
+ } else if((priv->server_alias != NULL) && (*priv->server_alias != '\0')) {
return priv->server_alias;
}
return NULL;
}
-const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy)
-{
+const gchar *
+purple_buddy_get_contact_alias(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
- PurpleContact *c;
+ PurpleContact *c = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
@@ -196,24 +387,27 @@ const char *purple_buddy_get_contact_alias(PurpleBuddy *buddy)
/* Search for an alias for the buddy. In order of precedence: */
/* The local buddy alias */
- if (priv->local_alias != NULL)
+ if(priv->local_alias != NULL) {
return priv->local_alias;
+ }
/* The contact alias */
c = purple_buddy_get_contact(buddy);
- if ((c != NULL) && (purple_contact_get_alias(c) != NULL))
+ if((c != NULL) && (purple_contact_get_alias(c) != NULL)) {
return purple_contact_get_alias(c);
+ }
/* The server alias */
- if ((priv->server_alias) && (*priv->server_alias))
+ if((priv->server_alias) && (*priv->server_alias != '\0')) {
return priv->server_alias;
+ }
/* The buddy's user name (i.e. no alias) */
return priv->name;
}
-const char *purple_buddy_get_alias(PurpleBuddy *buddy)
-{
+const gchar *
+purple_buddy_get_alias(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
@@ -222,201 +416,217 @@ const char *purple_buddy_get_alias(PurpleBuddy *buddy)
/* Search for an alias for the buddy. In order of precedence: */
/* The buddy alias */
- if (priv->local_alias != NULL)
+ if(priv->local_alias != NULL) {
return priv->local_alias;
+ }
/* The server alias */
- if ((priv->server_alias) && (*priv->server_alias))
+ if((priv->server_alias) && (*priv->server_alias != '\0')) {
return priv->server_alias;
+ }
/* The buddy's user name (i.e. no alias) */
return priv->name;
}
void
-purple_buddy_set_local_alias(PurpleBuddy *buddy, const char *alias)
-{
+purple_buddy_set_local_alias(PurpleBuddy *buddy, const gchar *alias) {
+ PurpleBuddyList *blist = NULL;
PurpleBuddyPrivate *priv = NULL;
- PurpleIMConversation *im;
- char *old_alias;
- char *new_alias = NULL;
+ PurpleIMConversation *im = NULL;
+ gchar *old_alias = NULL, *new_alias = NULL;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
priv = purple_buddy_get_instance_private(buddy);
- if ((alias != NULL) && (*alias != '\0'))
+ if((alias != NULL) && (*alias != '\0')) {
new_alias = purple_utf8_strip_unprintables(alias);
+ }
- if (purple_strequal(priv->local_alias, new_alias)) {
+ if(purple_strequal(priv->local_alias, new_alias)) {
g_free(new_alias);
return;
}
old_alias = priv->local_alias;
- if ((new_alias != NULL) && (*new_alias != '\0'))
+ if((new_alias != NULL) && (*new_alias != '\0')) {
priv->local_alias = new_alias;
- else {
+ } else {
priv->local_alias = NULL;
- g_free(new_alias); /* could be "\0" */
+ g_free(new_alias);
}
- g_object_notify_by_pspec(G_OBJECT(buddy),
- properties[PROP_LOCAL_ALIAS]);
+ g_object_notify_by_pspec(G_OBJECT(buddy), properties[PROP_LOCAL_ALIAS]);
- purple_blist_save_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
- purple_blist_update_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
+ blist = purple_blist_get_default();
+ purple_blist_save_node(blist, PURPLE_BLIST_NODE(buddy));
+ purple_blist_update_node(blist, PURPLE_BLIST_NODE(buddy));
- im = purple_conversations_find_im_with_account(priv->name,
- priv->account);
- if (im)
+ im = purple_conversations_find_im_with_account(priv->name, priv->account);
+ if(PURPLE_IS_IM_CONVERSATION(im)) {
purple_conversation_autoset_title(PURPLE_CONVERSATION(im));
+ }
- purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
- buddy, old_alias);
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased", buddy,
+ old_alias);
g_free(old_alias);
}
-const char *purple_buddy_get_local_alias(PurpleBuddy *buddy)
-{
+const gchar *
+purple_buddy_get_local_alias(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->local_alias;
}
void
-purple_buddy_set_server_alias(PurpleBuddy *buddy, const char *alias)
-{
+purple_buddy_set_server_alias(PurpleBuddy *buddy, const gchar *alias) {
+ PurpleBuddyList *blist = NULL;
PurpleBuddyPrivate *priv = NULL;
- PurpleIMConversation *im;
- char *old_alias;
- char *new_alias = NULL;
+ PurpleIMConversation *im = NULL;
+ gchar *old_alias = NULL, *new_alias = NULL;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
priv = purple_buddy_get_instance_private(buddy);
- if ((alias != NULL) && (*alias != '\0') && g_utf8_validate(alias, -1, NULL))
+ if((alias != NULL) && (*alias != '\0') && g_utf8_validate(alias, -1, NULL))
+ {
new_alias = purple_utf8_strip_unprintables(alias);
+ }
- if (purple_strequal(priv->server_alias, new_alias)) {
+ if(purple_strequal(priv->server_alias, new_alias)) {
g_free(new_alias);
+
return;
}
old_alias = priv->server_alias;
- if ((new_alias != NULL) && (*new_alias != '\0'))
+ if((new_alias != NULL) && (*new_alias != '\0')) {
priv->server_alias = new_alias;
- else {
+ } else {
priv->server_alias = NULL;
- g_free(new_alias); /* could be "\0"; */
+ g_free(new_alias);
}
- g_object_notify_by_pspec(G_OBJECT(buddy),
- properties[PROP_SERVER_ALIAS]);
+ g_object_notify_by_pspec(G_OBJECT(buddy), properties[PROP_SERVER_ALIAS]);
- purple_blist_save_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
- purple_blist_update_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
+ blist = purple_blist_get_default();
+ purple_blist_save_node(blist, PURPLE_BLIST_NODE(buddy));
+ purple_blist_update_node(blist, PURPLE_BLIST_NODE(buddy));
- im = purple_conversations_find_im_with_account(priv->name,
- priv->account);
- if (im)
+ im = purple_conversations_find_im_with_account(priv->name, priv->account);
+ if(PURPLE_IS_IM_CONVERSATION(im)) {
purple_conversation_autoset_title(PURPLE_CONVERSATION(im));
+ }
- purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
- buddy, old_alias);
+ purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased", buddy,
+ old_alias);
g_free(old_alias);
}
-const char *purple_buddy_get_server_alias(PurpleBuddy *buddy)
-{
+const gchar *
+purple_buddy_get_server_alias(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
- if ((priv->server_alias) && (*priv->server_alias))
+ if((priv->server_alias) && (*priv->server_alias != '\0')) {
return priv->server_alias;
+ }
return NULL;
}
-PurpleContact *purple_buddy_get_contact(PurpleBuddy *buddy)
-{
+PurpleContact *
+purple_buddy_get_contact(PurpleBuddy *buddy) {
+ PurpleBlistNode *parent = NULL;
+
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
- return PURPLE_CONTACT(PURPLE_BLIST_NODE(buddy)->parent);
+ parent = purple_blist_node_get_parent(PURPLE_BLIST_NODE(buddy));
+ if(PURPLE_IS_CONTACT(parent)) {
+ return PURPLE_CONTACT(parent);
+ }
+
+ return NULL;
}
-PurplePresence *purple_buddy_get_presence(PurpleBuddy *buddy)
-{
+PurplePresence *
+purple_buddy_get_presence(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->presence;
}
void
-purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status)
-{
+purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status) {
+ PurpleBuddyList *blist = NULL;
PurpleBuddyPrivate *priv = NULL;
- PurpleStatus *status;
- PurpleBlistNode *cnode;
- PurpleContact *contact;
- PurpleCountingNode *contact_counter, *group_counter;
+ PurpleStatus *status = NULL;
+ gpointer handle = NULL;
+
+ gboolean old_online = FALSE, new_online = FALSE;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
priv = purple_buddy_get_instance_private(buddy);
-
status = purple_presence_get_active_status(priv->presence);
+ blist = purple_blist_get_default();
+ handle = purple_blist_get_handle();
purple_debug_info("blistnodetypes", "Updating buddy status for %s (%s)\n",
- priv->name, purple_account_get_protocol_name(priv->account));
-
- if (purple_status_is_online(status) &&
- !purple_status_is_online(old_status)) {
-
- purple_signal_emit(purple_blist_get_handle(), "buddy-signed-on", buddy);
-
- cnode = PURPLE_BLIST_NODE(buddy)->parent;
+ priv->name,
+ purple_account_get_protocol_name(priv->account));
+
+ old_online = purple_status_is_online(old_status);
+ new_online = purple_status_is_online(status);
+
+ if(old_online != new_online) {
+ PurpleBlistNode *cnode = NULL, *gnode = NULL;
+ PurpleContact *contact = NULL;
+ PurpleCountingNode *contact_counter = NULL, *group_counter = NULL;
+ gint delta = 0, limit = 0;
+
+ if(new_online) {
+ purple_signal_emit(handle, "buddy-signed-on", buddy);
+ delta = 1;
+ limit = 1;
+ } else {
+ purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy), "last_seen",
+ time(NULL));
+
+ purple_signal_emit(handle, "buddy-signed-off", buddy);
+ delta = -1;
+ limit = 0;
+ }
+
+ cnode = purple_blist_node_get_parent(PURPLE_BLIST_NODE(buddy));
contact = PURPLE_CONTACT(cnode);
contact_counter = PURPLE_COUNTING_NODE(contact);
- group_counter = PURPLE_COUNTING_NODE(cnode->parent);
-
- purple_counting_node_change_online_count(contact_counter, +1);
- if (purple_counting_node_get_online_count(contact_counter) == 1)
- purple_counting_node_change_online_count(group_counter, +1);
- } else if (!purple_status_is_online(status) &&
- purple_status_is_online(old_status)) {
+ gnode = purple_blist_node_get_parent(cnode);
+ group_counter = PURPLE_COUNTING_NODE(gnode);
- purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy), "last_seen", time(NULL));
- purple_signal_emit(purple_blist_get_handle(), "buddy-signed-off", buddy);
-
- cnode = PURPLE_BLIST_NODE(buddy)->parent;
- contact = PURPLE_CONTACT(cnode);
- contact_counter = PURPLE_COUNTING_NODE(contact);
- group_counter = PURPLE_COUNTING_NODE(cnode->parent);
-
- purple_counting_node_change_online_count(contact_counter, -1);
- if (purple_counting_node_get_online_count(contact_counter) == 0)
- purple_counting_node_change_online_count(group_counter, -1);
+ purple_counting_node_change_online_count(contact_counter, delta);
+ if(purple_counting_node_get_online_count(contact_counter) == limit) {
+ purple_counting_node_change_online_count(group_counter, delta);
+ }
} else {
- purple_signal_emit(purple_blist_get_handle(),
- "buddy-status-changed", buddy, old_status,
- status);
+ purple_signal_emit(handle, "buddy-status-changed", buddy, old_status,
+ status);
}
/*
@@ -431,22 +641,22 @@ purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status)
*/
purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
- purple_blist_update_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
+ purple_blist_update_node(blist, PURPLE_BLIST_NODE(buddy));
}
-PurpleMediaCaps purple_buddy_get_media_caps(PurpleBuddy *buddy)
-{
+PurpleMediaCaps
+purple_buddy_get_media_caps(PurpleBuddy *buddy) {
PurpleBuddyPrivate *priv = NULL;
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), 0);
priv = purple_buddy_get_instance_private(buddy);
+
return priv->media_caps;
}
-void purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps)
-{
+void
+purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps) {
PurpleBuddyPrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_BUDDY(buddy));
@@ -454,236 +664,24 @@ void purple_buddy_set_media_caps(PurpleBuddy *buddy, PurpleMediaCaps media_caps)
priv = purple_buddy_get_instance_private(buddy);
priv->media_caps = media_caps;
- g_object_notify_by_pspec(G_OBJECT(buddy),
- properties[PROP_MEDIA_CAPS]);
+ g_object_notify_by_pspec(G_OBJECT(buddy), properties[PROP_MEDIA_CAPS]);
}
-PurpleGroup *purple_buddy_get_group(PurpleBuddy *buddy)
-{
+PurpleGroup *
+purple_buddy_get_group(PurpleBuddy *buddy) {
+ PurpleBlistNode *contact = NULL, *group = NULL;
+
g_return_val_if_fail(PURPLE_IS_BUDDY(buddy), NULL);
- if (PURPLE_BLIST_NODE(buddy)->parent == NULL)
+ contact = purple_blist_node_get_parent(PURPLE_BLIST_NODE(buddy));
+ if(!PURPLE_IS_CONTACT(contact)) {
return purple_blist_get_default_group();
-
- return PURPLE_GROUP(PURPLE_BLIST_NODE(buddy)->parent->parent);
-}
-
-/******************************************************************************
- * GObject Stuff
- *****************************************************************************/
-static void
-purple_buddy_set_property(GObject *obj, guint param_id, const GValue *value,
- GParamSpec *pspec)
-{
- PurpleBuddy *buddy = PURPLE_BUDDY(obj);
- PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(buddy);
-
- switch (param_id) {
- case PROP_NAME:
- if (priv->is_constructed)
- purple_buddy_set_name(buddy, g_value_get_string(value));
- else
- priv->name =
- purple_utf8_strip_unprintables(g_value_get_string(value));
- break;
- case PROP_LOCAL_ALIAS:
- if (priv->is_constructed)
- purple_buddy_set_local_alias(buddy, g_value_get_string(value));
- else
- priv->local_alias =
- purple_utf8_strip_unprintables(g_value_get_string(value));
- break;
- case PROP_SERVER_ALIAS:
- purple_buddy_set_server_alias(buddy, g_value_get_string(value));
- break;
- case PROP_ICON:
- purple_buddy_set_icon(buddy, g_value_get_pointer(value));
- break;
- case PROP_ACCOUNT:
- priv->account = g_value_get_object(value);
- break;
- case PROP_MEDIA_CAPS:
- purple_buddy_set_media_caps(buddy, g_value_get_enum(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-static void
-purple_buddy_get_property(GObject *obj, guint param_id, GValue *value,
- GParamSpec *pspec)
-{
- PurpleBuddy *buddy = PURPLE_BUDDY(obj);
-
- switch (param_id) {
- case PROP_NAME:
- g_value_set_string(value, purple_buddy_get_name(buddy));
- break;
- case PROP_LOCAL_ALIAS:
- g_value_set_string(value, purple_buddy_get_local_alias(buddy));
- break;
- case PROP_SERVER_ALIAS:
- g_value_set_string(value, purple_buddy_get_server_alias(buddy));
- break;
- case PROP_ICON:
- g_value_set_pointer(value, purple_buddy_get_icon(buddy));
- break;
- case PROP_ACCOUNT:
- g_value_set_object(value, purple_buddy_get_account(buddy));
- break;
- case PROP_PRESENCE:
- g_value_set_object(value, purple_buddy_get_presence(buddy));
- break;
- case PROP_MEDIA_CAPS:
- g_value_set_enum(value, purple_buddy_get_media_caps(buddy));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
}
-}
-
-static void
-purple_buddy_init(PurpleBuddy *buddy)
-{
-}
-
-static void
-purple_buddy_constructed(GObject *object) {
- PurpleBuddy *buddy = PURPLE_BUDDY(object);
- PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(buddy);
-
- G_OBJECT_CLASS(purple_buddy_parent_class)->constructed(object);
-
- priv->presence = PURPLE_PRESENCE(purple_buddy_presence_new(buddy));
- purple_presence_set_status_active(priv->presence, "offline", TRUE);
- purple_blist_new_node(purple_blist_get_default(),
- PURPLE_BLIST_NODE(buddy));
-
- priv->is_constructed = TRUE;
-}
-
-static void
-purple_buddy_dispose(GObject *object) {
- PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(PURPLE_BUDDY(object));
-
- if (priv->icon) {
- purple_buddy_icon_unref(priv->icon);
- priv->icon = NULL;
+ group = purple_blist_node_get_parent(contact);
+ if(PURPLE_IS_GROUP(group)) {
+ return PURPLE_GROUP(group);
}
- if (priv->presence) {
- g_object_unref(priv->presence);
- priv->presence = NULL;
- }
-
- G_OBJECT_CLASS(purple_buddy_parent_class)->dispose(object);
-}
-
-static void
-purple_buddy_finalize(GObject *object) {
- PurpleBuddy *buddy = PURPLE_BUDDY(object);
- PurpleBuddyPrivate *priv = purple_buddy_get_instance_private(buddy);
- PurpleProtocol *protocol;
-
- /*
- * Tell the owner protocol that we're about to free the buddy so it
- * can free proto_data
- */
- protocol = purple_protocols_find(purple_account_get_protocol_id(priv->account));
- if(protocol) {
- purple_protocol_client_buddy_free(PURPLE_PROTOCOL_CLIENT(protocol),
- buddy);
- }
-
- g_free(priv->name);
- g_free(priv->local_alias);
- g_free(priv->server_alias);
-
- G_OBJECT_CLASS(purple_buddy_parent_class)->finalize(object);
-}
-
-static void purple_buddy_class_init(PurpleBuddyClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
- obj_class->dispose = purple_buddy_dispose;
- obj_class->finalize = purple_buddy_finalize;
-
- /* Setup properties */
- obj_class->get_property = purple_buddy_get_property;
- obj_class->set_property = purple_buddy_set_property;
- obj_class->constructed = purple_buddy_constructed;
-
- properties[PROP_NAME] = g_param_spec_string(
- "name",
- "Name",
- "The name of the buddy.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
- );
-
- properties[PROP_LOCAL_ALIAS] = g_param_spec_string(
- "local-alias",
- "Local alias",
- "Local alias of thee buddy.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
- );
-
- properties[PROP_SERVER_ALIAS] = g_param_spec_string(
- "server-alias",
- "Server alias",
- "Server-side alias of the buddy.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
- );
-
- properties[PROP_ICON] = g_param_spec_pointer(
- "icon",
- "Buddy icon",
- "The icon for the buddy.",
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
- );
-
- properties[PROP_ACCOUNT] = g_param_spec_object(
- "account",
- "Account",
- "The account for the buddy.",
- PURPLE_TYPE_ACCOUNT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
- );
-
- properties[PROP_PRESENCE] = g_param_spec_object(
- "presence",
- "Presence",
- "The status information for the buddy.",
- PURPLE_TYPE_PRESENCE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS
- );
-
- properties[PROP_MEDIA_CAPS] = g_param_spec_enum(
- "media-caps",
- "Media capabilities",
- "The media capabilities of the buddy.",
- PURPLE_MEDIA_TYPE_CAPS, PURPLE_MEDIA_CAPS_NONE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
- );
-
- g_object_class_install_properties(obj_class, PROP_LAST, properties);
-}
-
-PurpleBuddy *
-purple_buddy_new(PurpleAccount *account, const char *name, const char *alias)
-{
- g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- return g_object_new(PURPLE_TYPE_BUDDY,
- "account", account,
- "name", name,
- "local-alias", alias,
- NULL);
+ return NULL;
}