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);
 	}