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