Mercurial > pidgin.yaz
changeset 28032:ab0dace4c688
merge of '676252faa4180c3a4995644d57dd0394f55d5db7'
and '9b3deec2188b0d6cd5015cc06c8de2f7d5696a59'
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Mon, 27 Jul 2009 03:33:32 +0000 |
parents | 02dd3b637d66 (diff) 7a456d5da878 (current diff) |
children | ce3bc26aa8cd |
files | |
diffstat | 2 files changed, 94 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/jabber/buddy.c Sun Jul 26 21:42:21 2009 +0000 +++ b/libpurple/protocols/jabber/buddy.c Mon Jul 27 03:33:32 2009 +0000 @@ -88,6 +88,83 @@ return jb; } +static gint resource_compare_cb(gconstpointer a, gconstpointer b) +{ + const JabberBuddyResource *jbra = a; + const JabberBuddyResource *jbrb = b; + JabberBuddyState state_a, state_b; + + if (jbra->priority != jbrb->priority) + return jbra->priority > jbrb->priority ? 1 : -1; + + /* Fold the states for easier comparison */ + switch (jbra->state) { + case JABBER_BUDDY_STATE_ONLINE: + case JABBER_BUDDY_STATE_CHAT: + state_a = JABBER_BUDDY_STATE_ONLINE; + break; + case JABBER_BUDDY_STATE_AWAY: + case JABBER_BUDDY_STATE_DND: + state_a = JABBER_BUDDY_STATE_AWAY; + break; + case JABBER_BUDDY_STATE_XA: + state_a = JABBER_BUDDY_STATE_XA; + break; + case JABBER_BUDDY_STATE_UNAVAILABLE: + state_a = JABBER_BUDDY_STATE_UNAVAILABLE; + break; + default: + state_a = JABBER_BUDDY_STATE_UNKNOWN; + break; + } + + switch (jbrb->state) { + case JABBER_BUDDY_STATE_ONLINE: + case JABBER_BUDDY_STATE_CHAT: + state_b = JABBER_BUDDY_STATE_ONLINE; + break; + case JABBER_BUDDY_STATE_AWAY: + case JABBER_BUDDY_STATE_DND: + state_b = JABBER_BUDDY_STATE_AWAY; + break; + case JABBER_BUDDY_STATE_XA: + state_b = JABBER_BUDDY_STATE_XA; + break; + case JABBER_BUDDY_STATE_UNAVAILABLE: + state_b = JABBER_BUDDY_STATE_UNAVAILABLE; + break; + default: + state_b = JABBER_BUDDY_STATE_UNKNOWN; + break; + } + + if (state_a == state_b) { + if (jbra->idle == jbrb->idle) + return 0; + else if ((jbra->idle && !jbrb->idle) || + (jbra->idle && jbrb->idle && jbra->idle < jbrb->idle)) + return -1; + else + return 1; + } + + if (state_a == JABBER_BUDDY_STATE_ONLINE) + return 1; + else if (state_a == JABBER_BUDDY_STATE_AWAY && + (state_b == JABBER_BUDDY_STATE_XA || + state_b == JABBER_BUDDY_STATE_UNAVAILABLE || + state_b == JABBER_BUDDY_STATE_UNKNOWN)) + return 1; + else if (state_a == JABBER_BUDDY_STATE_XA && + (state_b == JABBER_BUDDY_STATE_UNAVAILABLE || + state_b == JABBER_BUDDY_STATE_UNKNOWN)) + return 1; + else if (state_a == JABBER_BUDDY_STATE_UNAVAILABLE && + state_b == JABBER_BUDDY_STATE_UNKNOWN) + return 1; + + return -1; +} JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb, const char *resource) @@ -104,44 +181,8 @@ if (!jbr && !resource) { jbr = tmp; } else if (!resource) { - if (tmp->priority > jbr->priority) + if (resource_compare_cb(tmp, jbr) > 0) jbr = tmp; - else if (tmp->priority == jbr->priority) { - /* Determine if this resource is more available than the one we've currently chosen */ - switch(tmp->state) { - case JABBER_BUDDY_STATE_ONLINE: - case JABBER_BUDDY_STATE_CHAT: - /* This resource is online/chatty. Prefer to one which isn't either. */ - if (((jbr->state != JABBER_BUDDY_STATE_ONLINE) && (jbr->state != JABBER_BUDDY_STATE_CHAT)) - || (jbr->idle && !tmp->idle) - || (jbr->idle && tmp->idle && tmp->idle > jbr->idle)) - jbr = tmp; - break; - case JABBER_BUDDY_STATE_AWAY: - case JABBER_BUDDY_STATE_DND: - /* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */ - if (((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || - (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) - || (jbr->idle && !tmp->idle) - || (jbr->idle && tmp->idle && tmp->idle > jbr->idle)) - jbr = tmp; - break; - case JABBER_BUDDY_STATE_XA: - /* This resource is extended away. That's better than unavailable or unknown. */ - if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) - jbr = tmp; - break; - case JABBER_BUDDY_STATE_UNAVAILABLE: - /* This resource is unavailable. That's better than unknown. */ - if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR)) - jbr = tmp; - break; - case JABBER_BUDDY_STATE_UNKNOWN: - case JABBER_BUDDY_STATE_ERROR: - /* These are never preferable. */ - break; - } - } } else if(tmp->name) { if(!strcmp(tmp->name, resource)) { jbr = tmp;
--- a/libpurple/protocols/jabber/presence.c Sun Jul 26 21:42:21 2009 +0000 +++ b/libpurple/protocols/jabber/presence.c Mon Jul 27 03:33:32 2009 +0000 @@ -62,14 +62,16 @@ void jabber_presence_fake_to_self(JabberStream *js, PurpleStatus *status) { PurpleAccount *account; + PurplePresence *presence; const char *username; g_return_if_fail(js->user != NULL); account = purple_connection_get_account(js->gc); username = purple_connection_get_display_name(js->gc); + presence = purple_account_get_presence(account); if (status == NULL) - status = purple_account_get_active_status(account); + status = purple_presence_get_active_status(presence); if (purple_find_buddy(account, username)) { JabberBuddy *jb = jabber_buddy_find(js, username, TRUE); @@ -86,14 +88,23 @@ state == JABBER_BUDDY_STATE_UNKNOWN) { jabber_buddy_remove_resource(jb, js->user->resource); } else { - jabber_buddy_track_resource(jb, js->user->resource, priority, - state, msg); + jbr = jabber_buddy_track_resource(jb, js->user->resource, priority, + state, msg); + jbr->idle = purple_presence_is_idle(presence) ? + purple_presence_get_idle_time(presence) : 0; } if ((jbr = jabber_buddy_find_resource(jb, NULL))) { - purple_prpl_got_user_status(account, username, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL); + purple_prpl_got_user_status(account, username, + jabber_buddy_state_get_status_id(jbr->state), + "priority", jbr->priority, + jbr->status ? "message" : NULL, jbr->status, + NULL); + purple_prpl_got_user_idle(account, username, jbr->idle, jbr->idle); } else { - purple_prpl_got_user_status(account, username, "offline", msg ? "message" : NULL, msg, NULL); + purple_prpl_got_user_status(account, username, "offline", + msg ? "message" : NULL, msg, + NULL); } g_free(msg); }