libpurple/protocols/jabber/buddy.c

changeset 27965
d2f136953034
parent 27846
9c591a669ffe
child 27998
889b1fbece5b
equal deleted inserted replaced
27964:752edad344b3 27965:d2f136953034
86 g_free(realname); 86 g_free(realname);
87 87
88 return jb; 88 return jb;
89 } 89 }
90 90
91 static gint resource_compare_cb(gconstpointer a, gconstpointer b)
92 {
93 const JabberBuddyResource *jbra = a;
94 const JabberBuddyResource *jbrb = b;
95 JabberBuddyState state_a, state_b;
96
97 if (jbra->priority != jbrb->priority)
98 return jbra->priority > jbrb->priority ? 1 : -1;
99
100 /* Fold the states for easier comparison */
101 switch (jbra->state) {
102 case JABBER_BUDDY_STATE_ONLINE:
103 case JABBER_BUDDY_STATE_CHAT:
104 state_a = JABBER_BUDDY_STATE_ONLINE;
105 break;
106 case JABBER_BUDDY_STATE_AWAY:
107 case JABBER_BUDDY_STATE_DND:
108 state_a = JABBER_BUDDY_STATE_AWAY;
109 break;
110 case JABBER_BUDDY_STATE_XA:
111 state_a = JABBER_BUDDY_STATE_XA;
112 break;
113 case JABBER_BUDDY_STATE_UNAVAILABLE:
114 state_a = JABBER_BUDDY_STATE_UNAVAILABLE;
115 break;
116 default:
117 state_a = JABBER_BUDDY_STATE_UNKNOWN;
118 break;
119 }
120
121 switch (jbrb->state) {
122 case JABBER_BUDDY_STATE_ONLINE:
123 case JABBER_BUDDY_STATE_CHAT:
124 state_b = JABBER_BUDDY_STATE_ONLINE;
125 break;
126 case JABBER_BUDDY_STATE_AWAY:
127 case JABBER_BUDDY_STATE_DND:
128 state_b = JABBER_BUDDY_STATE_AWAY;
129 break;
130 case JABBER_BUDDY_STATE_XA:
131 state_b = JABBER_BUDDY_STATE_XA;
132 break;
133 case JABBER_BUDDY_STATE_UNAVAILABLE:
134 state_b = JABBER_BUDDY_STATE_UNAVAILABLE;
135 break;
136 default:
137 state_b = JABBER_BUDDY_STATE_UNKNOWN;
138 break;
139 }
140
141 if (state_a == state_b) {
142 if (jbra->idle == jbrb->idle)
143 return 0;
144 else if ((jbra->idle && !jbrb->idle) ||
145 (jbra->idle && jbrb->idle && jbra->idle < jbrb->idle))
146 return -1;
147 else
148 return 1;
149 }
150
151 if (state_a == JABBER_BUDDY_STATE_ONLINE)
152 return 1;
153 else if (state_a == JABBER_BUDDY_STATE_AWAY &&
154 (state_b == JABBER_BUDDY_STATE_XA ||
155 state_b == JABBER_BUDDY_STATE_UNAVAILABLE ||
156 state_b == JABBER_BUDDY_STATE_UNKNOWN))
157 return 1;
158 else if (state_a == JABBER_BUDDY_STATE_XA &&
159 (state_b == JABBER_BUDDY_STATE_UNAVAILABLE ||
160 state_b == JABBER_BUDDY_STATE_UNKNOWN))
161 return 1;
162 else if (state_a == JABBER_BUDDY_STATE_UNAVAILABLE &&
163 state_b == JABBER_BUDDY_STATE_UNKNOWN)
164 return 1;
165
166 return -1;
167 }
91 168
92 JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb, 169 JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb,
93 const char *resource) 170 const char *resource)
94 { 171 {
95 JabberBuddyResource *jbr = NULL; 172 JabberBuddyResource *jbr = NULL;
102 { 179 {
103 JabberBuddyResource *tmp = (JabberBuddyResource *) l->data; 180 JabberBuddyResource *tmp = (JabberBuddyResource *) l->data;
104 if (!jbr && !resource) { 181 if (!jbr && !resource) {
105 jbr = tmp; 182 jbr = tmp;
106 } else if (!resource) { 183 } else if (!resource) {
107 if (tmp->priority > jbr->priority) 184 if (resource_compare_cb(tmp, jbr) > 0)
108 jbr = tmp; 185 jbr = tmp;
109 else if (tmp->priority == jbr->priority) {
110 /* Determine if this resource is more available than the one we've currently chosen */
111 switch(tmp->state) {
112 case JABBER_BUDDY_STATE_ONLINE:
113 case JABBER_BUDDY_STATE_CHAT:
114 /* This resource is online/chatty. Prefer to one which isn't either. */
115 if (((jbr->state != JABBER_BUDDY_STATE_ONLINE) && (jbr->state != JABBER_BUDDY_STATE_CHAT))
116 || (jbr->idle && !tmp->idle)
117 || (jbr->idle && tmp->idle && tmp->idle > jbr->idle))
118 jbr = tmp;
119 break;
120 case JABBER_BUDDY_STATE_AWAY:
121 case JABBER_BUDDY_STATE_DND:
122 /* This resource is away/dnd. Prefer to one which is extended away, unavailable, or unknown. */
123 if (((jbr->state == JABBER_BUDDY_STATE_XA) || (jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) ||
124 (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR))
125 || (jbr->idle && !tmp->idle)
126 || (jbr->idle && tmp->idle && tmp->idle > jbr->idle))
127 jbr = tmp;
128 break;
129 case JABBER_BUDDY_STATE_XA:
130 /* This resource is extended away. That's better than unavailable or unknown. */
131 if ((jbr->state == JABBER_BUDDY_STATE_UNAVAILABLE) || (jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR))
132 jbr = tmp;
133 break;
134 case JABBER_BUDDY_STATE_UNAVAILABLE:
135 /* This resource is unavailable. That's better than unknown. */
136 if ((jbr->state == JABBER_BUDDY_STATE_UNKNOWN) || (jbr->state == JABBER_BUDDY_STATE_ERROR))
137 jbr = tmp;
138 break;
139 case JABBER_BUDDY_STATE_UNKNOWN:
140 case JABBER_BUDDY_STATE_ERROR:
141 /* These are never preferable. */
142 break;
143 }
144 }
145 } else if(tmp->name) { 186 } else if(tmp->name) {
146 if(!strcmp(tmp->name, resource)) { 187 if(!strcmp(tmp->name, resource)) {
147 jbr = tmp; 188 jbr = tmp;
148 break; 189 break;
149 } 190 }

mercurial