Mercurial > pidgin
annotate src/status.c @ 13967:99b9b58b19dd
[gaim-migrate @ 16523]
Fix a crazy MSN crash. Basically it's possible to have more than one
slplink associated with a given switchboard, but our code did not
allow for that. I think it happens when you're in a multi-user
chat and you do stuff with multiple users that involves slplinks.
Like maybe file transfer and buddy icon related stuff.
Tracking this down took an ungodly amount of time, but thanks to
Meebo for letting me do it :-)
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 20 Jul 2006 07:31:15 +0000 |
parents | a092ea4edd4e |
children | 8bda65b88e49 |
rev | line source |
---|---|
9944 | 1 /** |
10067 | 2 * @file status.c Status API |
9944 | 3 * @ingroup core |
4 * | |
6065 | 5 * gaim |
6 * | |
8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
9944 | 10 * |
6065 | 11 * This program is free software; you can redistribute it and/or modify |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
9949 | 25 #include "internal.h" |
6065 | 26 |
9949 | 27 #include "blist.h" |
10400 | 28 #include "core.h" |
11187 | 29 #include "dbus-maybe.h" |
9949 | 30 #include "debug.h" |
10337 | 31 #include "notify.h" |
9949 | 32 #include "prefs.h" |
6065 | 33 #include "status.h" |
34 | |
9949 | 35 /** |
36 * A type of status. | |
37 */ | |
38 struct _GaimStatusType | |
39 { | |
40 GaimStatusPrimitive primitive; | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
41 |
9949 | 42 char *id; |
43 char *name; | |
44 char *primary_attr_id; | |
45 | |
46 gboolean saveable; | |
47 gboolean user_settable; | |
48 gboolean independent; | |
49 | |
50 GList *attrs; | |
51 }; | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
52 |
9949 | 53 /** |
54 * A status attribute. | |
55 */ | |
56 struct _GaimStatusAttr | |
57 { | |
58 char *id; | |
59 char *name; | |
60 GaimValue *value_type; | |
61 }; | |
6065 | 62 |
9949 | 63 /** |
64 * A list of statuses. | |
65 */ | |
66 struct _GaimPresence | |
67 { | |
68 GaimPresenceContext context; | |
69 | |
70 gboolean idle; | |
71 time_t idle_time; | |
11249 | 72 time_t login_time; |
9949 | 73 |
74 GList *statuses; | |
75 GHashTable *status_table; | |
76 | |
77 GaimStatus *active_status; | |
6065 | 78 |
9949 | 79 union |
80 { | |
81 GaimAccount *account; | |
82 | |
83 struct | |
84 { | |
85 GaimConversation *conv; | |
86 char *user; | |
87 | |
88 } chat; | |
6065 | 89 |
9949 | 90 struct |
91 { | |
92 GaimAccount *account; | |
93 char *name; | |
94 size_t ref_count; | |
95 GList *buddies; | |
96 | |
97 } buddy; | |
98 | |
99 } u; | |
100 }; | |
101 | |
102 /** | |
103 * An active status. | |
104 */ | |
105 struct _GaimStatus | |
6065 | 106 { |
9949 | 107 GaimStatusType *type; |
108 GaimPresence *presence; | |
109 | |
110 const char *title; | |
6065 | 111 |
9949 | 112 gboolean active; |
6065 | 113 |
9949 | 114 GHashTable *attr_values; |
115 }; | |
6065 | 116 |
117 typedef struct | |
118 { | |
9949 | 119 GaimAccount *account; |
120 char *name; | |
121 } GaimStatusBuddyKey; | |
122 | |
123 static int primitive_scores[] = | |
124 { | |
125 0, /* unset */ | |
126 -500, /* offline */ | |
127 100, /* available */ | |
128 -75, /* unavailable */ | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
129 -50, /* invisible */ |
9949 | 130 -100, /* away */ |
10860 | 131 -200, /* extended away */ |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
132 -400, /* mobile */ |
9949 | 133 -10, /* idle, special case. */ |
134 -5 /* idle time, special case. */ | |
135 }; | |
136 | |
137 static GHashTable *buddy_presences = NULL; | |
138 | |
13039
b93240522baa
[gaim-migrate @ 15398]
Richard Laager <rlaager@wiktel.com>
parents:
12816
diff
changeset
|
139 #define SCORE_IDLE 8 |
b93240522baa
[gaim-migrate @ 15398]
Richard Laager <rlaager@wiktel.com>
parents:
12816
diff
changeset
|
140 #define SCORE_IDLE_TIME 9 |
9949 | 141 |
142 /************************************************************************** | |
10419 | 143 * GaimStatusPrimitive API |
144 **************************************************************************/ | |
145 static struct GaimStatusPrimitiveMap | |
146 { | |
147 GaimStatusPrimitive type; | |
148 const char *id; | |
149 const char *name; | |
150 | |
151 } const status_primitive_map[] = | |
152 { | |
153 { GAIM_STATUS_UNSET, "unset", N_("Unset") }, | |
154 { GAIM_STATUS_OFFLINE, "offline", N_("Offline") }, | |
155 { GAIM_STATUS_AVAILABLE, "available", N_("Available") }, | |
156 { GAIM_STATUS_UNAVAILABLE, "unavailable", N_("Unavailable") }, | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
157 { GAIM_STATUS_INVISIBLE, "invisible", N_("Invisible") }, |
10419 | 158 { GAIM_STATUS_AWAY, "away", N_("Away") }, |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
159 { GAIM_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended Away") }, |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
160 { GAIM_STATUS_MOBILE, "mobile", N_("Mobile") } |
10419 | 161 }; |
162 | |
163 const char * | |
164 gaim_primitive_get_id_from_type(GaimStatusPrimitive type) | |
165 { | |
166 int i; | |
167 | |
168 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) | |
169 { | |
170 if (type == status_primitive_map[i].type) | |
171 return status_primitive_map[i].id; | |
172 } | |
173 | |
174 return status_primitive_map[0].id; | |
175 } | |
176 | |
177 const char * | |
178 gaim_primitive_get_name_from_type(GaimStatusPrimitive type) | |
179 { | |
180 int i; | |
181 | |
182 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) | |
183 { | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
184 if (type == status_primitive_map[i].type) |
13248 | 185 return _(status_primitive_map[i].name); |
10419 | 186 } |
187 | |
13248 | 188 return _(status_primitive_map[0].name); |
10419 | 189 } |
190 | |
191 GaimStatusPrimitive | |
192 gaim_primitive_get_type_from_id(const char *id) | |
193 { | |
194 int i; | |
195 | |
196 g_return_val_if_fail(id != NULL, GAIM_STATUS_UNSET); | |
197 | |
198 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) | |
199 { | |
200 if (!strcmp(id, status_primitive_map[i].id)) | |
201 return status_primitive_map[i].type; | |
202 } | |
203 | |
204 return status_primitive_map[0].type; | |
205 } | |
206 | |
207 | |
208 /************************************************************************** | |
9949 | 209 * GaimStatusType API |
210 **************************************************************************/ | |
211 GaimStatusType * | |
212 gaim_status_type_new_full(GaimStatusPrimitive primitive, const char *id, | |
10009 | 213 const char *name, gboolean saveable, |
214 gboolean user_settable, gboolean independent) | |
9949 | 215 { |
216 GaimStatusType *status_type; | |
217 | |
218 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
219 | |
220 status_type = g_new0(GaimStatusType, 1); | |
11187 | 221 GAIM_DBUS_REGISTER_POINTER(status_type, GaimStatusType); |
9949 | 222 |
223 status_type->primitive = primitive; | |
224 status_type->saveable = saveable; | |
225 status_type->user_settable = user_settable; | |
226 status_type->independent = independent; | |
227 | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
228 if (id != NULL) |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
229 status_type->id = g_strdup(id); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
230 else |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
231 status_type->id = g_strdup(gaim_primitive_get_id_from_type(primitive)); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
232 |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
233 if (name != NULL) |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
234 status_type->name = g_strdup(name); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
235 else |
13248 | 236 status_type->name = g_strdup(gaim_primitive_get_name_from_type(primitive)); |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
237 |
9949 | 238 return status_type; |
239 } | |
240 | |
241 GaimStatusType * | |
242 gaim_status_type_new(GaimStatusPrimitive primitive, const char *id, | |
10009 | 243 const char *name, gboolean user_settable) |
9949 | 244 { |
245 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
246 | |
247 return gaim_status_type_new_full(primitive, id, name, FALSE, | |
248 user_settable, FALSE); | |
249 } | |
250 | |
251 GaimStatusType * | |
252 gaim_status_type_new_with_attrs(GaimStatusPrimitive primitive, | |
253 const char *id, const char *name, | |
254 gboolean saveable, gboolean user_settable, | |
255 gboolean independent, const char *attr_id, | |
256 const char *attr_name, GaimValue *attr_value, | |
257 ...) | |
258 { | |
259 GaimStatusType *status_type; | |
260 va_list args; | |
261 | |
262 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
10012 | 263 g_return_val_if_fail(attr_id != NULL, NULL); |
9949 | 264 g_return_val_if_fail(attr_name != NULL, NULL); |
265 g_return_val_if_fail(attr_value != NULL, NULL); | |
266 | |
267 status_type = gaim_status_type_new_full(primitive, id, name, saveable, | |
268 user_settable, independent); | |
269 | |
10010 | 270 /* Add the first attribute */ |
9949 | 271 gaim_status_type_add_attr(status_type, attr_id, attr_name, attr_value); |
272 | |
273 va_start(args, attr_value); | |
274 gaim_status_type_add_attrs_vargs(status_type, args); | |
275 va_end(args); | |
276 | |
277 return status_type; | |
278 } | |
279 | |
280 void | |
281 gaim_status_type_destroy(GaimStatusType *status_type) | |
282 { | |
283 GList *l; | |
284 | |
285 g_return_if_fail(status_type != NULL); | |
286 | |
287 g_free(status_type->id); | |
288 g_free(status_type->name); | |
289 | |
290 if (status_type->primary_attr_id != NULL) | |
291 g_free(status_type->primary_attr_id); | |
292 | |
293 if (status_type->attrs != NULL) | |
294 { | |
295 for (l = status_type->attrs; l != NULL; l = l->next) | |
296 gaim_status_attr_destroy((GaimStatusAttr *)l->data); | |
297 | |
298 g_list_free(status_type->attrs); | |
299 } | |
300 | |
11187 | 301 GAIM_DBUS_UNREGISTER_POINTER(status_type); |
9949 | 302 g_free(status_type); |
303 } | |
304 | |
305 void | |
306 gaim_status_type_set_primary_attr(GaimStatusType *status_type, const char *id) | |
307 { | |
308 g_return_if_fail(status_type != NULL); | |
309 | |
310 if (status_type->primary_attr_id != NULL) | |
311 g_free(status_type->primary_attr_id); | |
312 | |
313 status_type->primary_attr_id = (id == NULL ? NULL : g_strdup(id)); | |
314 } | |
315 | |
316 void | |
10197 | 317 gaim_status_type_add_attr(GaimStatusType *status_type, const char *id, |
9949 | 318 const char *name, GaimValue *value) |
319 { | |
320 GaimStatusAttr *attr; | |
321 | |
322 g_return_if_fail(status_type != NULL); | |
323 g_return_if_fail(id != NULL); | |
324 g_return_if_fail(name != NULL); | |
325 g_return_if_fail(value != NULL); | |
326 | |
327 attr = gaim_status_attr_new(id, name, value); | |
328 | |
329 status_type->attrs = g_list_append(status_type->attrs, attr); | |
330 } | |
331 | |
332 void | |
333 gaim_status_type_add_attrs_vargs(GaimStatusType *status_type, va_list args) | |
334 { | |
335 const char *id, *name; | |
336 GaimValue *value; | |
337 | |
338 g_return_if_fail(status_type != NULL); | |
339 | |
340 while ((id = va_arg(args, const char *)) != NULL) | |
341 { | |
342 name = va_arg(args, const char *); | |
343 g_return_if_fail(name != NULL); | |
344 | |
345 value = va_arg(args, GaimValue *); | |
346 g_return_if_fail(value != NULL); | |
6065 | 347 |
9949 | 348 gaim_status_type_add_attr(status_type, id, name, value); |
349 } | |
350 } | |
351 | |
10010 | 352 void |
353 gaim_status_type_add_attrs(GaimStatusType *status_type, const char *id, | |
354 const char *name, GaimValue *value, ...) | |
355 { | |
356 va_list args; | |
357 | |
358 g_return_if_fail(status_type != NULL); | |
359 g_return_if_fail(id != NULL); | |
360 g_return_if_fail(name != NULL); | |
361 g_return_if_fail(value != NULL); | |
362 | |
363 /* Add the first attribute */ | |
364 gaim_status_type_add_attr(status_type, id, name, value); | |
365 | |
366 va_start(args, value); | |
367 gaim_status_type_add_attrs_vargs(status_type, args); | |
368 va_end(args); | |
369 } | |
370 | |
9949 | 371 GaimStatusPrimitive |
372 gaim_status_type_get_primitive(const GaimStatusType *status_type) | |
373 { | |
374 g_return_val_if_fail(status_type != NULL, GAIM_STATUS_UNSET); | |
375 | |
376 return status_type->primitive; | |
377 } | |
378 | |
379 const char * | |
380 gaim_status_type_get_id(const GaimStatusType *status_type) | |
381 { | |
382 g_return_val_if_fail(status_type != NULL, NULL); | |
383 | |
384 return status_type->id; | |
385 } | |
386 | |
387 const char * | |
388 gaim_status_type_get_name(const GaimStatusType *status_type) | |
389 { | |
390 g_return_val_if_fail(status_type != NULL, NULL); | |
391 | |
392 return status_type->name; | |
393 } | |
394 | |
395 gboolean | |
396 gaim_status_type_is_saveable(const GaimStatusType *status_type) | |
397 { | |
398 g_return_val_if_fail(status_type != NULL, FALSE); | |
399 | |
400 return status_type->saveable; | |
401 } | |
402 | |
403 gboolean | |
404 gaim_status_type_is_user_settable(const GaimStatusType *status_type) | |
405 { | |
406 g_return_val_if_fail(status_type != NULL, FALSE); | |
407 | |
408 return status_type->user_settable; | |
409 } | |
410 | |
411 gboolean | |
412 gaim_status_type_is_independent(const GaimStatusType *status_type) | |
413 { | |
414 g_return_val_if_fail(status_type != NULL, FALSE); | |
415 | |
416 return status_type->independent; | |
417 } | |
418 | |
419 gboolean | |
10067 | 420 gaim_status_type_is_exclusive(const GaimStatusType *status_type) |
421 { | |
422 g_return_val_if_fail(status_type != NULL, FALSE); | |
423 | |
424 return !status_type->independent; | |
425 } | |
426 | |
427 gboolean | |
9949 | 428 gaim_status_type_is_available(const GaimStatusType *status_type) |
429 { | |
430 GaimStatusPrimitive primitive; | |
431 | |
432 g_return_val_if_fail(status_type != NULL, FALSE); | |
433 | |
434 primitive = gaim_status_type_get_primitive(status_type); | |
435 | |
12587 | 436 return (primitive == GAIM_STATUS_AVAILABLE); |
9949 | 437 } |
438 | |
439 const char * | |
440 gaim_status_type_get_primary_attr(const GaimStatusType *status_type) | |
441 { | |
442 g_return_val_if_fail(status_type != NULL, NULL); | |
443 | |
444 return status_type->primary_attr_id; | |
445 } | |
446 | |
447 GaimStatusAttr * | |
448 gaim_status_type_get_attr(const GaimStatusType *status_type, const char *id) | |
449 { | |
450 GList *l; | |
451 | |
452 g_return_val_if_fail(status_type != NULL, NULL); | |
453 g_return_val_if_fail(id != NULL, NULL); | |
454 | |
455 for (l = status_type->attrs; l != NULL; l = l->next) | |
456 { | |
457 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
458 | |
459 if (!strcmp(gaim_status_attr_get_id(attr), id)) | |
460 return attr; | |
461 } | |
462 | |
463 return NULL; | |
464 } | |
465 | |
466 const GList * | |
467 gaim_status_type_get_attrs(const GaimStatusType *status_type) | |
468 { | |
469 g_return_val_if_fail(status_type != NULL, NULL); | |
470 | |
471 return status_type->attrs; | |
472 } | |
473 | |
10348 | 474 const GaimStatusType * |
475 gaim_status_type_find_with_id(GList *status_types, const char *id) | |
476 { | |
477 GaimStatusType *status_type; | |
478 | |
479 g_return_val_if_fail(id != NULL, NULL); | |
480 | |
481 while (status_types != NULL) | |
482 { | |
483 status_type = status_types->data; | |
484 | |
485 if (!strcmp(id, status_type->id)) | |
486 return status_type; | |
10895 | 487 |
488 status_types = status_types->next; | |
10348 | 489 } |
490 | |
491 return NULL; | |
492 } | |
493 | |
9949 | 494 |
495 /************************************************************************** | |
496 * GaimStatusAttr API | |
497 **************************************************************************/ | |
498 GaimStatusAttr * | |
499 gaim_status_attr_new(const char *id, const char *name, GaimValue *value_type) | |
500 { | |
501 GaimStatusAttr *attr; | |
502 | |
503 g_return_val_if_fail(id != NULL, NULL); | |
504 g_return_val_if_fail(name != NULL, NULL); | |
505 g_return_val_if_fail(value_type != NULL, NULL); | |
506 | |
507 attr = g_new0(GaimStatusAttr, 1); | |
11187 | 508 GAIM_DBUS_REGISTER_POINTER(attr, GaimStatusAttr); |
9949 | 509 |
510 attr->id = g_strdup(id); | |
511 attr->name = g_strdup(name); | |
512 attr->value_type = value_type; | |
513 | |
514 return attr; | |
515 } | |
516 | |
517 void | |
518 gaim_status_attr_destroy(GaimStatusAttr *attr) | |
519 { | |
520 g_return_if_fail(attr != NULL); | |
521 | |
522 g_free(attr->id); | |
523 g_free(attr->name); | |
524 | |
525 gaim_value_destroy(attr->value_type); | |
526 | |
11187 | 527 GAIM_DBUS_UNREGISTER_POINTER(attr); |
9949 | 528 g_free(attr); |
529 } | |
530 | |
531 const char * | |
532 gaim_status_attr_get_id(const GaimStatusAttr *attr) | |
533 { | |
534 g_return_val_if_fail(attr != NULL, NULL); | |
535 | |
536 return attr->id; | |
537 } | |
538 | |
539 const char * | |
540 gaim_status_attr_get_name(const GaimStatusAttr *attr) | |
541 { | |
542 g_return_val_if_fail(attr != NULL, NULL); | |
543 | |
544 return attr->name; | |
545 } | |
546 | |
547 GaimValue * | |
11249 | 548 gaim_status_attr_get_value(const GaimStatusAttr *attr) |
9949 | 549 { |
550 g_return_val_if_fail(attr != NULL, NULL); | |
551 | |
552 return attr->value_type; | |
553 } | |
554 | |
555 | |
556 /************************************************************************** | |
557 * GaimStatus API | |
558 **************************************************************************/ | |
559 GaimStatus * | |
560 gaim_status_new(GaimStatusType *status_type, GaimPresence *presence) | |
561 { | |
562 GaimStatus *status; | |
563 const GList *l; | |
564 | |
565 g_return_val_if_fail(status_type != NULL, NULL); | |
566 g_return_val_if_fail(presence != NULL, NULL); | |
567 | |
568 status = g_new0(GaimStatus, 1); | |
11187 | 569 GAIM_DBUS_REGISTER_POINTER(status, GaimStatus); |
9949 | 570 |
571 status->type = status_type; | |
572 status->presence = presence; | |
573 | |
574 status->attr_values = | |
575 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
576 (GDestroyNotify)gaim_value_destroy); | |
577 | |
578 for (l = gaim_status_type_get_attrs(status_type); l != NULL; l = l->next) | |
579 { | |
580 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
11249 | 581 GaimValue *value = gaim_status_attr_get_value(attr); |
9949 | 582 GaimValue *new_value = gaim_value_dup(value); |
583 | |
584 g_hash_table_insert(status->attr_values, | |
10197 | 585 g_strdup(gaim_status_attr_get_id(attr)), |
586 new_value); | |
9949 | 587 } |
588 | |
589 return status; | |
590 } | |
591 | |
10754 | 592 /* |
593 * TODO: If the GaimStatus is in a GaimPresence, then | |
594 * remove it from the GaimPresence? | |
595 */ | |
9949 | 596 void |
597 gaim_status_destroy(GaimStatus *status) | |
598 { | |
599 g_return_if_fail(status != NULL); | |
600 | |
601 g_hash_table_destroy(status->attr_values); | |
602 | |
11187 | 603 GAIM_DBUS_UNREGISTER_POINTER(status); |
9949 | 604 g_free(status); |
605 } | |
6065 | 606 |
607 static void | |
9949 | 608 notify_buddy_status_update(GaimBuddy *buddy, GaimPresence *presence, |
609 GaimStatus *old_status, GaimStatus *new_status) | |
610 { | |
611 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | |
612 | |
11698 | 613 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 614 { |
615 time_t current_time = time(NULL); | |
616 const char *buddy_alias = gaim_buddy_get_alias(buddy); | |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
617 char *tmp; |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
618 GaimLog *log; |
9949 | 619 |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
620 if (old_status != NULL) |
9949 | 621 { |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
622 tmp = g_strdup_printf(_("%s changed status from %s to %s"), buddy_alias, |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
623 gaim_status_get_name(old_status), |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
624 gaim_status_get_name(new_status)); |
9949 | 625 } |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
626 else |
9949 | 627 { |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
628 /* old_status == NULL when an independent status is toggled. */ |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
629 |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
630 if (gaim_status_is_active(new_status)) |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
631 { |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
632 tmp = g_strdup_printf(_("%s is now %s"), buddy_alias, |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
633 gaim_status_get_name(new_status)); |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
634 } |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
635 else |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
636 { |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
637 tmp = g_strdup_printf(_("%s is no longer %s"), buddy_alias, |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
638 gaim_status_get_name(new_status)); |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
639 } |
13506
c358be635301
[gaim-migrate @ 15882]
Richard Laager <rlaager@wiktel.com>
parents:
13373
diff
changeset
|
640 } |
9949 | 641 |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
642 log = gaim_account_get_log(buddy->account, FALSE); |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
643 if (log != NULL) |
9949 | 644 { |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
645 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
646 current_time, tmp); |
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
647 } |
9949 | 648 |
13537
207f974ca030
[gaim-migrate @ 15914]
Richard Laager <rlaager@wiktel.com>
parents:
13515
diff
changeset
|
649 g_free(tmp); |
9949 | 650 } |
651 | |
10012 | 652 if (ops != NULL && ops->update != NULL) |
653 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 654 } |
655 | |
656 static void | |
657 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
658 GaimStatus *new_status) |
6065 | 659 { |
9949 | 660 GaimPresenceContext context = gaim_presence_get_context(presence); |
661 | |
662 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) | |
663 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
664 GaimAccount *account = gaim_presence_get_account(presence); |
9949 | 665 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); |
666 | |
10400 | 667 if (gaim_account_get_enabled(account, gaim_core_get_ui())) |
10447 | 668 gaim_prpl_change_account_status(account, old_status, new_status); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
669 |
9949 | 670 if (ops != NULL && ops->status_changed != NULL) |
671 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
672 ops->status_changed(account, new_status); |
9949 | 673 } |
674 } | |
675 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
676 { | |
677 const GList *l; | |
678 | |
679 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
680 { | |
681 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
682 old_status, new_status); | |
683 } | |
684 } | |
685 } | |
686 | |
10204 | 687 static void |
688 status_has_changed(GaimStatus *status) | |
9949 | 689 { |
690 GaimPresence *presence; | |
691 GaimStatus *old_status; | |
692 | |
693 presence = gaim_status_get_presence(status); | |
694 | |
10204 | 695 /* |
696 * If this status is exclusive, then we must be setting it to "active." | |
697 * Since we are setting it to active, we want to set the currently | |
698 * active status to "inactive." | |
699 */ | |
700 if (gaim_status_is_exclusive(status)) | |
9949 | 701 { |
10754 | 702 old_status = gaim_presence_get_active_status(presence); |
10760 | 703 if (old_status != NULL && (old_status != status)) |
10754 | 704 old_status->active = FALSE; |
705 presence->active_status = status; | |
9949 | 706 } |
10754 | 707 else |
708 old_status = NULL; | |
9949 | 709 |
10204 | 710 notify_status_update(presence, old_status, status); |
711 } | |
712 | |
713 void | |
714 gaim_status_set_active(GaimStatus *status, gboolean active) | |
715 { | |
13192 | 716 gaim_status_set_active_with_attrs_list(status, active, NULL); |
10204 | 717 } |
718 | |
11249 | 719 /* |
720 * This used to parse the va_list directly, but now it creates a GList | |
721 * and passes it to gaim_status_set_active_with_attrs_list(). That | |
722 * function was created because accounts.c needs to pass a GList of | |
723 * attributes to the status API. | |
724 */ | |
10204 | 725 void |
726 gaim_status_set_active_with_attrs(GaimStatus *status, gboolean active, va_list args) | |
727 { | |
11249 | 728 GList *attrs = NULL; |
729 const gchar *id; | |
730 gpointer data; | |
731 | |
732 if (args != NULL) | |
733 { | |
734 while ((id = va_arg(args, const char *)) != NULL) | |
735 { | |
736 attrs = g_list_append(attrs, (char *)id); | |
737 data = va_arg(args, void *); | |
738 attrs = g_list_append(attrs, data); | |
739 } | |
740 } | |
741 gaim_status_set_active_with_attrs_list(status, active, attrs); | |
742 g_list_free(attrs); | |
743 } | |
744 | |
745 void | |
746 gaim_status_set_active_with_attrs_list(GaimStatus *status, gboolean active, | |
747 const GList *attrs) | |
748 { | |
10204 | 749 gboolean changed = FALSE; |
13373 | 750 const GList *l; |
751 GList *specified_attr_ids = NULL; | |
752 GaimStatusType *status_type; | |
10204 | 753 |
10714 | 754 g_return_if_fail(status != NULL); |
755 | |
10204 | 756 if (!active && gaim_status_is_exclusive(status)) |
757 { | |
758 gaim_debug_error("status", | |
759 "Cannot deactivate an exclusive status (%s).\n", | |
760 gaim_status_get_id(status)); | |
761 return; | |
762 } | |
763 | |
764 if (status->active != active) | |
10738 | 765 { |
10204 | 766 changed = TRUE; |
10738 | 767 } |
10204 | 768 |
9949 | 769 status->active = active; |
6065 | 770 |
10204 | 771 /* Set any attributes */ |
13373 | 772 l = attrs; |
773 while (l != NULL) | |
10204 | 774 { |
13373 | 775 const gchar *id; |
10204 | 776 GaimValue *value; |
11249 | 777 |
13373 | 778 id = l->data; |
779 l = l->next; | |
10204 | 780 value = gaim_status_get_attr_value(status, id); |
10713 | 781 if (value == NULL) |
782 { | |
783 gaim_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
10714 | 784 "not supported.\n", id, status->type->name); |
10713 | 785 /* Skip over the data and move on to the next attribute */ |
13373 | 786 l = l->next; |
10713 | 787 continue; |
788 } | |
789 | |
13373 | 790 specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id); |
791 | |
10204 | 792 if (value->type == GAIM_TYPE_STRING) |
793 { | |
13373 | 794 const gchar *string_data = l->data; |
795 l = l->next; | |
10204 | 796 if (((string_data == NULL) && (value->data.string_data == NULL)) || |
797 ((string_data != NULL) && (value->data.string_data != NULL) && | |
798 !strcmp(string_data, value->data.string_data))) | |
799 { | |
800 continue; | |
801 } | |
802 gaim_status_set_attr_string(status, id, string_data); | |
803 changed = TRUE; | |
804 } | |
805 else if (value->type == GAIM_TYPE_INT) | |
806 { | |
13373 | 807 int int_data = GPOINTER_TO_INT(l->data); |
808 l = l->next; | |
10204 | 809 if (int_data == value->data.int_data) |
810 continue; | |
811 gaim_status_set_attr_int(status, id, int_data); | |
812 changed = TRUE; | |
813 } | |
814 else if (value->type == GAIM_TYPE_BOOLEAN) | |
815 { | |
13373 | 816 gboolean boolean_data = GPOINTER_TO_INT(l->data); |
817 l = l->next; | |
10204 | 818 if (boolean_data == value->data.boolean_data) |
819 continue; | |
13373 | 820 gaim_status_set_attr_boolean(status, id, boolean_data); |
10204 | 821 changed = TRUE; |
822 } | |
823 else | |
824 { | |
825 /* We don't know what the data is--skip over it */ | |
13373 | 826 l = l->next; |
10204 | 827 } |
828 } | |
829 | |
13373 | 830 /* Reset any unspecified attributes to their default value */ |
831 status_type = gaim_status_get_type(status); | |
832 l = gaim_status_type_get_attrs(status_type); | |
833 while (l != NULL) | |
834 { | |
835 GaimStatusAttr *attr; | |
836 | |
837 attr = l->data; | |
838 if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) | |
839 { | |
840 GaimValue *default_value; | |
841 default_value = gaim_status_attr_get_value(attr); | |
842 if (default_value->type == GAIM_TYPE_STRING) | |
843 gaim_status_set_attr_string(status, attr->id, | |
844 gaim_value_get_string(default_value)); | |
845 else if (default_value->type == GAIM_TYPE_INT) | |
846 gaim_status_set_attr_int(status, attr->id, | |
847 gaim_value_get_int(default_value)); | |
848 else if (default_value->type == GAIM_TYPE_BOOLEAN) | |
849 gaim_status_set_attr_boolean(status, attr->id, | |
850 gaim_value_get_boolean(default_value)); | |
851 changed = TRUE; | |
852 } | |
853 | |
854 l = l->next; | |
855 } | |
856 g_list_free(specified_attr_ids); | |
857 | |
10204 | 858 if (!changed) |
859 return; | |
860 status_has_changed(status); | |
9949 | 861 } |
862 | |
863 void | |
864 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
865 gboolean value) | |
866 { | |
867 GaimValue *attr_value; | |
868 | |
869 g_return_if_fail(status != NULL); | |
870 g_return_if_fail(id != NULL); | |
871 | |
10197 | 872 /* Make sure this attribute exists and is the correct type. */ |
873 attr_value = gaim_status_get_attr_value(status, id); | |
874 g_return_if_fail(attr_value != NULL); | |
9949 | 875 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); |
876 | |
877 gaim_value_set_boolean(attr_value, value); | |
878 } | |
879 | |
880 void | |
881 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
882 { | |
883 GaimValue *attr_value; | |
884 | |
885 g_return_if_fail(status != NULL); | |
886 g_return_if_fail(id != NULL); | |
887 | |
10197 | 888 /* Make sure this attribute exists and is the correct type. */ |
889 attr_value = gaim_status_get_attr_value(status, id); | |
890 g_return_if_fail(attr_value != NULL); | |
9949 | 891 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); |
892 | |
893 gaim_value_set_int(attr_value, value); | |
6065 | 894 } |
895 | |
9949 | 896 void |
897 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
898 const char *value) | |
899 { | |
900 GaimValue *attr_value; | |
901 | |
902 g_return_if_fail(status != NULL); | |
903 g_return_if_fail(id != NULL); | |
904 | |
10197 | 905 /* Make sure this attribute exists and is the correct type. */ |
10196 | 906 attr_value = gaim_status_get_attr_value(status, id); |
12434 | 907 /* This used to be g_return_if_fail, but it's failing a LOT, so |
908 * let's generate a log error for now. */ | |
909 /* g_return_if_fail(attr_value != NULL); */ | |
910 if (attr_value == NULL) { | |
911 gaim_debug_error("status", | |
912 "Attempted to set status attribute '%s' for " | |
913 "status '%s', which is not legal. Fix " | |
914 "this!\n", id, | |
915 gaim_status_type_get_name(gaim_status_get_type(status))); | |
916 return; | |
917 } | |
9949 | 918 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); |
919 | |
920 gaim_value_set_string(attr_value, value); | |
921 } | |
922 | |
923 GaimStatusType * | |
924 gaim_status_get_type(const GaimStatus *status) | |
925 { | |
926 g_return_val_if_fail(status != NULL, NULL); | |
927 | |
928 return status->type; | |
929 } | |
930 | |
931 GaimPresence * | |
932 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 933 { |
9949 | 934 g_return_val_if_fail(status != NULL, NULL); |
935 | |
936 return status->presence; | |
937 } | |
938 | |
939 const char * | |
940 gaim_status_get_id(const GaimStatus *status) | |
941 { | |
942 g_return_val_if_fail(status != NULL, NULL); | |
943 | |
944 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
945 } | |
946 | |
947 const char * | |
948 gaim_status_get_name(const GaimStatus *status) | |
949 { | |
950 g_return_val_if_fail(status != NULL, NULL); | |
951 | |
952 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
953 } | |
954 | |
955 gboolean | |
956 gaim_status_is_independent(const GaimStatus *status) | |
957 { | |
958 g_return_val_if_fail(status != NULL, FALSE); | |
959 | |
960 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
961 } | |
962 | |
963 gboolean | |
10067 | 964 gaim_status_is_exclusive(const GaimStatus *status) |
965 { | |
966 g_return_val_if_fail(status != NULL, FALSE); | |
967 | |
968 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
969 } | |
970 | |
971 gboolean | |
9949 | 972 gaim_status_is_available(const GaimStatus *status) |
973 { | |
974 g_return_val_if_fail(status != NULL, FALSE); | |
975 | |
976 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
977 } | |
6216 | 978 |
9949 | 979 gboolean |
980 gaim_status_is_active(const GaimStatus *status) | |
981 { | |
982 g_return_val_if_fail(status != NULL, FALSE); | |
983 | |
984 return status->active; | |
985 } | |
986 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
987 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
988 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
989 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
990 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
991 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
992 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
993 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
994 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
995 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
996 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
997 primitive != GAIM_STATUS_OFFLINE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
998 } |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
999 |
9949 | 1000 GaimValue * |
1001 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
1002 { | |
1003 g_return_val_if_fail(status != NULL, NULL); | |
1004 g_return_val_if_fail(id != NULL, NULL); | |
1005 | |
1006 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
1007 } | |
1008 | |
1009 gboolean | |
1010 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
1011 { | |
1012 const GaimValue *value; | |
1013 | |
1014 g_return_val_if_fail(status != NULL, FALSE); | |
1015 g_return_val_if_fail(id != NULL, FALSE); | |
1016 | |
1017 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
1018 return FALSE; | |
1019 | |
10197 | 1020 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_BOOLEAN, FALSE); |
9949 | 1021 |
1022 return gaim_value_get_boolean(value); | |
1023 } | |
1024 | |
1025 int | |
1026 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
1027 { | |
1028 const GaimValue *value; | |
1029 | |
10507 | 1030 g_return_val_if_fail(status != NULL, 0); |
1031 g_return_val_if_fail(id != NULL, 0); | |
9949 | 1032 |
1033 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10507 | 1034 return 0; |
9949 | 1035 |
1036 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
1037 | |
1038 return gaim_value_get_int(value); | |
1039 } | |
1040 | |
1041 const char * | |
1042 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
1043 { | |
1044 const GaimValue *value; | |
1045 | |
10507 | 1046 g_return_val_if_fail(status != NULL, NULL); |
1047 g_return_val_if_fail(id != NULL, NULL); | |
9949 | 1048 |
1049 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10504 | 1050 return NULL; |
9949 | 1051 |
1052 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
1053 | |
1054 return gaim_value_get_string(value); | |
1055 } | |
1056 | |
1057 gint | |
1058 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
1059 { | |
1060 GaimStatusType *type1, *type2; | |
1061 int score1 = 0, score2 = 0; | |
6065 | 1062 |
9949 | 1063 if ((status1 == NULL && status2 == NULL) || |
1064 (status1 == status2)) | |
1065 { | |
1066 return 0; | |
1067 } | |
1068 else if (status1 == NULL) | |
1069 return 1; | |
1070 else if (status2 == NULL) | |
1071 return -1; | |
1072 | |
1073 type1 = gaim_status_get_type(status1); | |
1074 type2 = gaim_status_get_type(status2); | |
1075 | |
1076 if (gaim_status_is_active(status1)) | |
1077 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
1078 | |
1079 if (gaim_status_is_active(status2)) | |
1080 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
1081 | |
1082 if (score1 > score2) | |
1083 return -1; | |
1084 else if (score1 < score2) | |
1085 return 1; | |
1086 | |
1087 return 0; | |
1088 } | |
1089 | |
1090 | |
1091 /************************************************************************** | |
1092 * GaimPresence API | |
1093 **************************************************************************/ | |
1094 GaimPresence * | |
1095 gaim_presence_new(GaimPresenceContext context) | |
1096 { | |
1097 GaimPresence *presence; | |
1098 | |
1099 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
1100 | |
1101 presence = g_new0(GaimPresence, 1); | |
11187 | 1102 GAIM_DBUS_REGISTER_POINTER(presence, GaimPresence); |
9949 | 1103 |
1104 presence->context = context; | |
1105 | |
1106 presence->status_table = | |
10009 | 1107 g_hash_table_new_full(g_str_hash, g_str_equal, |
11638 | 1108 g_free, NULL); |
9949 | 1109 |
1110 return presence; | |
1111 } | |
1112 | |
1113 GaimPresence * | |
1114 gaim_presence_new_for_account(GaimAccount *account) | |
1115 { | |
10012 | 1116 GaimPresence *presence = NULL; |
9949 | 1117 g_return_val_if_fail(account != NULL, NULL); |
1118 | |
1119 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
1120 presence->u.account = account; | |
10006 | 1121 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 1122 |
1123 return presence; | |
1124 } | |
1125 | |
1126 GaimPresence * | |
1127 gaim_presence_new_for_conv(GaimConversation *conv) | |
1128 { | |
1129 GaimPresence *presence; | |
1130 | |
1131 g_return_val_if_fail(conv != NULL, NULL); | |
1132 | |
1133 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
1134 presence->u.chat.conv = conv; | |
10006 | 1135 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 1136 |
1137 return presence; | |
1138 } | |
6216 | 1139 |
9949 | 1140 GaimPresence * |
1141 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
1142 { | |
1143 GaimPresence *presence; | |
1144 GaimStatusBuddyKey *key; | |
10006 | 1145 GaimAccount *account; |
9949 | 1146 |
1147 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 1148 account = buddy->account; |
9949 | 1149 |
1150 key = g_new0(GaimStatusBuddyKey, 1); | |
1151 key->account = buddy->account; | |
1152 key->name = g_strdup(buddy->name); | |
10006 | 1153 |
1154 presence = g_hash_table_lookup(buddy_presences, key); | |
1155 if (presence == NULL) | |
9949 | 1156 { |
1157 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
1158 | |
1159 presence->u.buddy.name = g_strdup(buddy->name); | |
1160 presence->u.buddy.account = buddy->account; | |
10006 | 1161 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 1162 |
1163 g_hash_table_insert(buddy_presences, key, presence); | |
1164 } | |
1165 else | |
1166 { | |
1167 g_free(key->name); | |
1168 g_free(key); | |
1169 } | |
1170 | |
1171 presence->u.buddy.ref_count++; | |
1172 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
1173 buddy); | |
1174 | |
1175 return presence; | |
1176 } | |
1177 | |
1178 void | |
1179 gaim_presence_destroy(GaimPresence *presence) | |
1180 { | |
1181 g_return_if_fail(presence != NULL); | |
6216 | 1182 |
9949 | 1183 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1184 { | |
1185 GaimStatusBuddyKey key; | |
1186 | |
10077 | 1187 if(presence->u.buddy.ref_count != 0) |
1188 return; | |
9949 | 1189 |
1190 key.account = presence->u.buddy.account; | |
1191 key.name = presence->u.buddy.name; | |
1192 | |
1193 g_hash_table_remove(buddy_presences, &key); | |
1194 | |
1195 if (presence->u.buddy.name != NULL) | |
1196 g_free(presence->u.buddy.name); | |
1197 } | |
1198 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1199 { | |
1200 if (presence->u.chat.user != NULL) | |
1201 g_free(presence->u.chat.user); | |
1202 } | |
1203 | |
11638 | 1204 if (presence->statuses != NULL) { |
1205 g_list_foreach(presence->statuses, (GFunc)gaim_status_destroy, NULL); | |
9949 | 1206 g_list_free(presence->statuses); |
11638 | 1207 } |
9949 | 1208 |
1209 g_hash_table_destroy(presence->status_table); | |
1210 | |
11187 | 1211 GAIM_DBUS_UNREGISTER_POINTER(presence); |
9949 | 1212 g_free(presence); |
1213 } | |
1214 | |
10580 | 1215 /* |
1216 * TODO: Maybe we should cal gaim_presence_destroy() after we | |
1217 * decrement the ref count? I don't see why we should | |
1218 * make other places do it manually when we can do it here. | |
1219 */ | |
9949 | 1220 void |
1221 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
1222 { | |
1223 g_return_if_fail(presence != NULL); | |
1224 g_return_if_fail(buddy != NULL); | |
1225 g_return_if_fail(gaim_presence_get_context(presence) == | |
1226 GAIM_PRESENCE_CONTEXT_BUDDY); | |
1227 | |
1228 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
1229 { | |
1230 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
1231 buddy); | |
1232 presence->u.buddy.ref_count--; | |
1233 } | |
6065 | 1234 } |
1235 | |
9949 | 1236 void |
1237 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
1238 { | |
1239 g_return_if_fail(presence != NULL); | |
1240 g_return_if_fail(status != NULL); | |
1241 | |
1242 presence->statuses = g_list_append(presence->statuses, status); | |
1243 | |
1244 g_hash_table_insert(presence->status_table, | |
1245 g_strdup(gaim_status_get_id(status)), status); | |
1246 } | |
1247 | |
1248 void | |
11318 | 1249 gaim_presence_add_list(GaimPresence *presence, const GList *source_list) |
9949 | 1250 { |
1251 const GList *l; | |
1252 | |
1253 g_return_if_fail(presence != NULL); | |
1254 g_return_if_fail(source_list != NULL); | |
1255 | |
1256 for (l = source_list; l != NULL; l = l->next) | |
1257 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
1258 } | |
1259 | |
1260 void | |
1261 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
1262 gboolean active) | |
1263 { | |
1264 GaimStatus *status; | |
1265 | |
1266 g_return_if_fail(presence != NULL); | |
1267 g_return_if_fail(status_id != NULL); | |
1268 | |
1269 status = gaim_presence_get_status(presence, status_id); | |
1270 | |
1271 g_return_if_fail(status != NULL); | |
10348 | 1272 /* TODO: Should we do the following? */ |
1273 /* g_return_if_fail(active == status->active); */ | |
9949 | 1274 |
10067 | 1275 if (gaim_status_is_exclusive(status)) |
9949 | 1276 { |
1277 if (!active) | |
1278 { | |
1279 gaim_debug_warning("status", | |
1280 "Attempted to set a non-independent status " | |
1281 "(%s) inactive. Only independent statuses " | |
1282 "can be specifically marked inactive.", | |
1283 status_id); | |
1284 return; | |
1285 } | |
1286 } | |
1287 | |
1288 gaim_status_set_active(status, active); | |
1289 } | |
1290 | |
1291 void | |
1292 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
1293 { | |
10754 | 1294 gaim_presence_set_status_active(presence, status_id, TRUE); |
9949 | 1295 } |
1296 | |
1297 static void | |
1298 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
1299 time_t current_time, gboolean old_idle, gboolean idle) | |
1300 { | |
13867
a092ea4edd4e
[gaim-migrate @ 16333]
Sadrul Habib Chowdhury <imadil@gmail.com>
parents:
13663
diff
changeset
|
1301 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); |
9949 | 1302 |
1303 if (!old_idle && idle) | |
1304 { | |
11698 | 1305 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 1306 { |
13507
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1307 GaimLog *log = gaim_account_get_log(buddy->account, FALSE); |
9949 | 1308 |
13507
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1309 if (log != NULL) |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1310 { |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1311 char *tmp = g_strdup_printf(_("%s became idle"), |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1312 gaim_buddy_get_alias(buddy)); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1313 |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1314 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1315 gaim_buddy_get_alias(buddy), current_time, tmp); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1316 g_free(tmp); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1317 } |
9949 | 1318 } |
1319 } | |
1320 else if (old_idle && !idle) | |
1321 { | |
11698 | 1322 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 1323 { |
13507
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1324 GaimLog *log = gaim_account_get_log(buddy->account, FALSE); |
9949 | 1325 |
13507
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1326 if (log != NULL) |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1327 { |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1328 char *tmp = g_strdup_printf(_("%s became unidle"), |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1329 gaim_buddy_get_alias(buddy)); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1330 |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1331 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1332 gaim_buddy_get_alias(buddy), current_time, tmp); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1333 g_free(tmp); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1334 } |
9949 | 1335 } |
1336 } | |
1337 | |
11935
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1338 if (old_idle != idle) |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1339 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle-changed", buddy, |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1340 old_idle, idle); |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1341 |
10378 | 1342 gaim_contact_invalidate_priority_buddy(gaim_buddy_get_contact(buddy)); |
9949 | 1343 |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1344 /* Should this be done here? It'd perhaps make more sense to |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1345 * connect to buddy-[un]idle signals and update from there |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1346 */ |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1347 |
9949 | 1348 if (ops != NULL && ops->update != NULL) |
1349 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
1350 } | |
1351 | |
1352 void | |
1353 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
1354 { | |
1355 gboolean old_idle; | |
1356 | |
1357 g_return_if_fail(presence != NULL); | |
1358 | |
1359 if (presence->idle == idle && presence->idle_time == idle_time) | |
1360 return; | |
1361 | |
1362 old_idle = presence->idle; | |
1363 presence->idle = idle; | |
1364 presence->idle_time = (idle ? idle_time : 0); | |
1365 | |
1366 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1367 { | |
1368 const GList *l; | |
1369 time_t current_time = time(NULL); | |
1370 | |
1371 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
1372 { | |
1373 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
1374 old_idle, idle); | |
1375 } | |
1376 } | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1377 else if(gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_ACCOUNT) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1378 { |
11975 | 1379 GaimAccount *account; |
1380 GaimConnection *gc; | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1381 GaimPluginProtocolInfo *prpl_info = NULL; |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1382 |
11975 | 1383 account = gaim_presence_get_account(presence); |
12145
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1384 |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1385 if (gaim_prefs_get_bool("/core/logging/log_system")) |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1386 { |
13507
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1387 GaimLog *log = gaim_account_get_log(account, FALSE); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1388 |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1389 if (log != NULL) |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1390 { |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1391 char *msg; |
11975 | 1392 |
13507
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1393 if (idle) |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1394 msg = g_strdup_printf(_("+++ %s became idle"), gaim_account_get_username(account)); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1395 else |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1396 msg = g_strdup_printf(_("+++ %s became unidle"), gaim_account_get_username(account)); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1397 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1398 gaim_account_get_username(account), |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1399 idle_time, msg); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1400 g_free(msg); |
702107dd58f1
[gaim-migrate @ 15883]
Richard Laager <rlaager@wiktel.com>
parents:
13506
diff
changeset
|
1401 } |
12145
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1402 } |
11975 | 1403 |
1404 gc = gaim_account_get_connection(account); | |
1405 | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1406 if (gc != NULL && gc->prpl != NULL) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1407 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1408 |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1409 if (prpl_info && g_list_find(gaim_connections_get_all(), gc) && |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1410 prpl_info->set_idle) |
13657
f9b24d282c91
[gaim-migrate @ 16059]
Evan Schoenberg <evan.s@dreskin.net>
parents:
13537
diff
changeset
|
1411 prpl_info->set_idle(gc, (idle ? (time(NULL) - idle_time) : 0)); |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1412 } |
9949 | 1413 } |
1414 | |
1415 void | |
10006 | 1416 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
1417 { | |
1418 g_return_if_fail(presence != NULL); | |
1419 | |
1420 if (presence->login_time == login_time) | |
1421 return; | |
1422 | |
1423 presence->login_time = login_time; | |
1424 } | |
1425 | |
9949 | 1426 GaimPresenceContext |
1427 gaim_presence_get_context(const GaimPresence *presence) | |
1428 { | |
1429 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
1430 | |
1431 return presence->context; | |
1432 } | |
1433 | |
1434 GaimAccount * | |
1435 gaim_presence_get_account(const GaimPresence *presence) | |
1436 { | |
1437 GaimPresenceContext context; | |
1438 | |
1439 g_return_val_if_fail(presence != NULL, NULL); | |
1440 | |
1441 context = gaim_presence_get_context(presence); | |
1442 | |
1443 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
1444 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1445 | |
1446 return presence->u.account; | |
1447 } | |
1448 | |
1449 GaimConversation * | |
1450 gaim_presence_get_conversation(const GaimPresence *presence) | |
1451 { | |
1452 g_return_val_if_fail(presence != NULL, NULL); | |
1453 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1454 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1455 | |
1456 return presence->u.chat.conv; | |
1457 } | |
1458 | |
1459 const char * | |
1460 gaim_presence_get_chat_user(const GaimPresence *presence) | |
1461 { | |
1462 g_return_val_if_fail(presence != NULL, NULL); | |
1463 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1464 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1465 | |
1466 return presence->u.chat.user; | |
1467 } | |
1468 | |
1469 const GList * | |
1470 gaim_presence_get_buddies(const GaimPresence *presence) | |
1471 { | |
1472 g_return_val_if_fail(presence != NULL, NULL); | |
1473 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1474 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1475 | |
1476 return presence->u.buddy.buddies; | |
1477 } | |
1478 | |
1479 const GList * | |
1480 gaim_presence_get_statuses(const GaimPresence *presence) | |
1481 { | |
1482 g_return_val_if_fail(presence != NULL, NULL); | |
1483 | |
1484 return presence->statuses; | |
1485 } | |
1486 | |
1487 GaimStatus * | |
1488 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
1489 { | |
1490 GaimStatus *status; | |
10006 | 1491 const GList *l = NULL; |
9949 | 1492 |
1493 g_return_val_if_fail(presence != NULL, NULL); | |
1494 g_return_val_if_fail(status_id != NULL, NULL); | |
1495 | |
10006 | 1496 /* What's the purpose of this hash table? */ |
10012 | 1497 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
10006 | 1498 status_id); |
10012 | 1499 |
10006 | 1500 if (status == NULL) { |
10012 | 1501 for (l = gaim_presence_get_statuses(presence); |
10006 | 1502 l != NULL && status == NULL; l = l->next) |
1503 { | |
1504 GaimStatus *temp_status = l->data; | |
10012 | 1505 |
10006 | 1506 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
1507 status = temp_status; | |
1508 } | |
1509 | |
1510 if (status != NULL) | |
1511 g_hash_table_insert(presence->status_table, | |
1512 g_strdup(gaim_status_get_id(status)), status); | |
10012 | 1513 } |
9949 | 1514 |
1515 return status; | |
1516 } | |
1517 | |
1518 GaimStatus * | |
1519 gaim_presence_get_active_status(const GaimPresence *presence) | |
1520 { | |
1521 g_return_val_if_fail(presence != NULL, NULL); | |
1522 | |
1523 return presence->active_status; | |
1524 } | |
1525 | |
1526 gboolean | |
1527 gaim_presence_is_available(const GaimPresence *presence) | |
1528 { | |
1529 GaimStatus *status; | |
1530 | |
1531 g_return_val_if_fail(presence != NULL, FALSE); | |
1532 | |
1533 status = gaim_presence_get_active_status(presence); | |
1534 | |
1535 return ((status != NULL && gaim_status_is_available(status)) && | |
1536 !gaim_presence_is_idle(presence)); | |
1537 } | |
1538 | |
1539 gboolean | |
1540 gaim_presence_is_online(const GaimPresence *presence) | |
1541 { | |
1542 GaimStatus *status; | |
1543 | |
1544 g_return_val_if_fail(presence != NULL, FALSE); | |
1545 | |
1546 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
1547 return FALSE; | |
1548 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1549 return gaim_status_is_online(status); |
9949 | 1550 } |
1551 | |
1552 gboolean | |
1553 gaim_presence_is_status_active(const GaimPresence *presence, | |
1554 const char *status_id) | |
1555 { | |
1556 GaimStatus *status; | |
1557 | |
1558 g_return_val_if_fail(presence != NULL, FALSE); | |
1559 g_return_val_if_fail(status_id != NULL, FALSE); | |
1560 | |
1561 status = gaim_presence_get_status(presence, status_id); | |
1562 | |
1563 return (status != NULL && gaim_status_is_active(status)); | |
1564 } | |
1565 | |
1566 gboolean | |
1567 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
1568 GaimStatusPrimitive primitive) | |
1569 { | |
1570 GaimStatus *status; | |
1571 GaimStatusType *status_type; | |
1572 | |
1573 g_return_val_if_fail(presence != NULL, FALSE); | |
1574 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
1575 | |
1576 status = gaim_presence_get_active_status(presence); | |
1577 status_type = gaim_status_get_type(status); | |
1578 | |
1579 if (gaim_status_type_get_primitive(status_type) == primitive) | |
1580 return TRUE; | |
6065 | 1581 |
1582 return FALSE; | |
1583 } | |
1584 | |
9949 | 1585 gboolean |
1586 gaim_presence_is_idle(const GaimPresence *presence) | |
6065 | 1587 { |
9949 | 1588 g_return_val_if_fail(presence != NULL, FALSE); |
1589 | |
11634 | 1590 return gaim_presence_is_online(presence) && presence->idle; |
6065 | 1591 } |
1592 | |
9949 | 1593 time_t |
1594 gaim_presence_get_idle_time(const GaimPresence *presence) | |
6065 | 1595 { |
9949 | 1596 g_return_val_if_fail(presence != NULL, 0); |
6065 | 1597 |
9949 | 1598 return presence->idle_time; |
1599 } | |
6065 | 1600 |
10567 | 1601 time_t |
1602 gaim_presence_get_login_time(const GaimPresence *presence) | |
1603 { | |
1604 g_return_val_if_fail(presence != NULL, 0); | |
1605 | |
11973 | 1606 return gaim_presence_is_online(presence) ? presence->login_time : 0; |
10567 | 1607 } |
1608 | |
9949 | 1609 gint |
1610 gaim_presence_compare(const GaimPresence *presence1, | |
1611 const GaimPresence *presence2) | |
6065 | 1612 { |
9949 | 1613 gboolean idle1, idle2; |
10860 | 1614 time_t idle_time_1, idle_time_2; |
9949 | 1615 int score1 = 0, score2 = 0; |
1616 const GList *l; | |
6065 | 1617 |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
1618 if (presence1 == presence2) |
9949 | 1619 return 0; |
1620 else if (presence1 == NULL) | |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1621 return 1; |
9949 | 1622 else if (presence2 == NULL) |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1623 return -1; |
6065 | 1624 |
9949 | 1625 /* Compute the score of the first set of statuses. */ |
1626 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1627 { | |
1628 GaimStatus *status = (GaimStatus *)l->data; | |
1629 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1630 |
9949 | 1631 if (gaim_status_is_active(status)) |
1632 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1633 } |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
1634 score1 += gaim_account_get_int(gaim_presence_get_account(presence1), "score", 0); |
6065 | 1635 |
9949 | 1636 /* Compute the score of the second set of statuses. */ |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1637 for (l = gaim_presence_get_statuses(presence2); l != NULL; l = l->next) |
9949 | 1638 { |
1639 GaimStatus *status = (GaimStatus *)l->data; | |
1640 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1641 |
9949 | 1642 if (gaim_status_is_active(status)) |
1643 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1644 } |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
1645 score2 += gaim_account_get_int(gaim_presence_get_account(presence2), "score", 0); |
6065 | 1646 |
9949 | 1647 idle1 = gaim_presence_is_idle(presence1); |
1648 idle2 = gaim_presence_is_idle(presence2); | |
6065 | 1649 |
9949 | 1650 if (idle1) |
1651 score1 += primitive_scores[SCORE_IDLE]; | |
6065 | 1652 |
9949 | 1653 if (idle2) |
1654 score2 += primitive_scores[SCORE_IDLE]; | |
6065 | 1655 |
10860 | 1656 idle_time_1 = time(NULL) - gaim_presence_get_idle_time(presence1); |
1657 idle_time_2 = time(NULL) - gaim_presence_get_idle_time(presence2); | |
6065 | 1658 |
9949 | 1659 if (idle_time_1 > idle_time_2) |
1660 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
1661 else if (idle_time_1 < idle_time_2) | |
1662 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
6065 | 1663 |
9949 | 1664 if (score1 < score2) |
1665 return 1; | |
1666 else if (score1 > score2) | |
1667 return -1; | |
1668 | |
1669 return 0; | |
1670 } | |
1671 | |
6065 | 1672 |
9949 | 1673 /************************************************************************** |
1674 * Status subsystem | |
1675 **************************************************************************/ | |
1676 static void | |
12816 | 1677 score_pref_changed_cb(const char *name, GaimPrefType type, |
1678 gconstpointer value, gpointer data) | |
9949 | 1679 { |
1680 int index = GPOINTER_TO_INT(data); | |
6065 | 1681 |
9949 | 1682 primitive_scores[index] = GPOINTER_TO_INT(value); |
6065 | 1683 } |
1684 | |
10519 | 1685 static guint |
10006 | 1686 gaim_buddy_presences_hash(gconstpointer key) |
1687 { | |
10012 | 1688 const GaimStatusBuddyKey *me = key; |
1689 guint ret; | |
1690 char *str; | |
1691 | |
1692 str = g_strdup_printf("%p%s", me->account, me->name); | |
1693 ret = g_str_hash(str); | |
1694 g_free(str); | |
1695 | |
1696 return ret; | |
10006 | 1697 } |
1698 | |
10519 | 1699 static gboolean |
10006 | 1700 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
1701 { | |
1702 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
1703 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
1704 | |
10012 | 1705 if(key_a->account == key_b->account && |
1706 !strcmp(key_a->name, key_b->name)) | |
10006 | 1707 return TRUE; |
1708 else | |
1709 return FALSE; | |
1710 } | |
1711 | |
10519 | 1712 static void |
1713 gaim_buddy_presences_key_free(gpointer a) | |
1714 { | |
1715 GaimStatusBuddyKey *key = (GaimStatusBuddyKey *)a; | |
1716 g_free(key->name); | |
1717 g_free(key); | |
1718 } | |
1719 | |
10087 | 1720 void * |
10418 | 1721 gaim_status_get_handle(void) { |
10087 | 1722 static int handle; |
1723 | |
1724 return &handle; | |
1725 } | |
1726 | |
9949 | 1727 void |
10418 | 1728 gaim_status_init(void) |
6065 | 1729 { |
10418 | 1730 void *handle = gaim_status_get_handle; |
10087 | 1731 |
9949 | 1732 gaim_prefs_add_none("/core/status"); |
1733 gaim_prefs_add_none("/core/status/scores"); | |
6065 | 1734 |
9949 | 1735 gaim_prefs_add_int("/core/status/scores/offline", |
1736 primitive_scores[GAIM_STATUS_OFFLINE]); | |
1737 gaim_prefs_add_int("/core/status/scores/available", | |
1738 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1739 gaim_prefs_add_int("/core/status/scores/invisible", |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1740 primitive_scores[GAIM_STATUS_INVISIBLE]); |
9949 | 1741 gaim_prefs_add_int("/core/status/scores/away", |
1742 primitive_scores[GAIM_STATUS_AWAY]); | |
1743 gaim_prefs_add_int("/core/status/scores/extended_away", | |
1744 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
1745 gaim_prefs_add_int("/core/status/scores/idle", | |
1746 primitive_scores[SCORE_IDLE]); | |
6065 | 1747 |
10087 | 1748 gaim_prefs_connect_callback(handle, "/core/status/scores/offline", |
9949 | 1749 score_pref_changed_cb, |
1750 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
10087 | 1751 gaim_prefs_connect_callback(handle, "/core/status/scores/available", |
9949 | 1752 score_pref_changed_cb, |
1753 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1754 gaim_prefs_connect_callback(handle, "/core/status/scores/invisible", |
9949 | 1755 score_pref_changed_cb, |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1756 GINT_TO_POINTER(GAIM_STATUS_INVISIBLE)); |
10087 | 1757 gaim_prefs_connect_callback(handle, "/core/status/scores/away", |
9949 | 1758 score_pref_changed_cb, |
1759 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
10087 | 1760 gaim_prefs_connect_callback(handle, "/core/status/scores/extended_away", |
9949 | 1761 score_pref_changed_cb, |
1762 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
10087 | 1763 gaim_prefs_connect_callback(handle, "/core/status/scores/idle", |
9949 | 1764 score_pref_changed_cb, |
1765 GINT_TO_POINTER(SCORE_IDLE)); | |
10006 | 1766 |
10519 | 1767 buddy_presences = g_hash_table_new_full(gaim_buddy_presences_hash, |
1768 gaim_buddy_presences_equal, | |
1769 gaim_buddy_presences_key_free, NULL); | |
9949 | 1770 } |
6065 | 1771 |
9949 | 1772 void |
10418 | 1773 gaim_status_uninit(void) |
9949 | 1774 { |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1775 if (buddy_presences != NULL) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1776 { |
10077 | 1777 g_hash_table_destroy(buddy_presences); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1778 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1779 buddy_presences = NULL; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1780 } |
9949 | 1781 } |