Mercurial > pidgin
annotate src/status.c @ 11634:c7305c2d650b
[gaim-migrate @ 13910]
Two fixes:
1. Don't print 2 assertion failed warnings when showing the tooltip
of an idle with no status message Yahoo! buddy. This is the change
in gtkblist.c
2. When an idle Yahoo! buddy signs offline, we continued to show
the buddy as idle. If a buddy is offline then they are NOT idle.
This is the change in status.c
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 10 Oct 2005 04:55:42 +0000 |
parents | 45d54425dc65 |
children | 3a05b53a589e |
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 | |
10754 | 600 /* TODO: Don't do this is if the status is exclusive */ |
9949 | 601 gaim_status_set_active(status, FALSE); |
602 | |
603 g_hash_table_destroy(status->attr_values); | |
604 | |
11187 | 605 GAIM_DBUS_UNREGISTER_POINTER(status); |
9949 | 606 g_free(status); |
607 } | |
6065 | 608 |
609 static void | |
9949 | 610 notify_buddy_status_update(GaimBuddy *buddy, GaimPresence *presence, |
611 GaimStatus *old_status, GaimStatus *new_status) | |
612 { | |
613 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | |
614 | |
615 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
616 gaim_prefs_get_bool("/core/logging/log_away_state")) | |
617 { | |
618 time_t current_time = time(NULL); | |
619 const char *buddy_alias = gaim_buddy_get_alias(buddy); | |
620 char *tmp = NULL; | |
621 | |
11624 | 622 if (((old_status == NULL) || !gaim_status_is_available(old_status)) && |
9949 | 623 gaim_status_is_available(new_status)) |
624 { | |
625 tmp = g_strdup_printf(_("%s came back"), buddy_alias); | |
626 } | |
11624 | 627 else if ((old_status != NULL) && gaim_status_is_available(old_status) && |
9949 | 628 !gaim_status_is_available(new_status)) |
629 { | |
630 tmp = g_strdup_printf(_("%s went away"), buddy_alias); | |
631 } | |
632 | |
633 if (tmp != NULL) | |
634 { | |
635 GaimLog *log = gaim_account_get_log(buddy->account); | |
636 | |
637 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, | |
638 current_time, tmp); | |
639 g_free(tmp); | |
640 } | |
641 } | |
642 | |
10012 | 643 if (ops != NULL && ops->update != NULL) |
644 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 645 } |
646 | |
647 static void | |
648 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
649 GaimStatus *new_status) |
6065 | 650 { |
9949 | 651 GaimPresenceContext context = gaim_presence_get_context(presence); |
652 | |
653 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) | |
654 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
655 GaimAccount *account = gaim_presence_get_account(presence); |
9949 | 656 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); |
657 | |
10400 | 658 if (gaim_account_get_enabled(account, gaim_core_get_ui())) |
10447 | 659 gaim_prpl_change_account_status(account, old_status, new_status); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
660 |
9949 | 661 if (ops != NULL && ops->status_changed != NULL) |
662 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
663 ops->status_changed(account, new_status); |
9949 | 664 } |
665 } | |
666 else if (context == GAIM_PRESENCE_CONTEXT_CONV) | |
667 { | |
668 #if 0 | |
669 GaimConversationUiOps *ops; | |
670 GaimConversation *conv; | |
671 | |
672 conv = gaim_status_get_conversation(new_status); | |
10348 | 673 /* |
674 * TODO: Probably need to do some of the following here? This is copied | |
675 * from some old status code that was removed. | |
676 * | |
677 * char *tmp = g_strdup_printf(_("%s logged in."), alias); | |
678 * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
679 * g_free(tmp); | |
680 * | |
681 * char *tmp = g_strdup_printf(_("%s logged out."), alias); | |
682 * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
683 * g_free(tmp); | |
684 * | |
685 * char *tmp = g_strdup_printf(_("%s signed off"), alias); | |
686 * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); | |
687 * g_free(tmp); | |
688 * | |
689 * serv_got_typing_stopped(gc, name); | |
690 * | |
691 * gaim_conversation_update(c, GAIM_CONV_UPDATE_AWAY); | |
692 */ | |
9949 | 693 #endif |
694 } | |
695 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
696 { | |
697 const GList *l; | |
698 | |
699 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
700 { | |
701 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
702 old_status, new_status); | |
703 } | |
10348 | 704 |
705 /* | |
706 * TODO: Maybe we should do this here? | |
707 * GaimLog *log = gaim_account_get_log(account); | |
708 * char *tmp = g_strdup_printf(_("%s signed on"), alias); | |
709 * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); | |
710 * g_free(tmp); | |
711 */ | |
9949 | 712 } |
713 } | |
714 | |
10204 | 715 static void |
716 status_has_changed(GaimStatus *status) | |
9949 | 717 { |
718 GaimPresence *presence; | |
719 GaimStatus *old_status; | |
720 | |
721 presence = gaim_status_get_presence(status); | |
722 | |
10204 | 723 /* |
724 * If this status is exclusive, then we must be setting it to "active." | |
725 * Since we are setting it to active, we want to set the currently | |
726 * active status to "inactive." | |
727 */ | |
728 if (gaim_status_is_exclusive(status)) | |
9949 | 729 { |
10754 | 730 old_status = gaim_presence_get_active_status(presence); |
10760 | 731 if (old_status != NULL && (old_status != status)) |
10754 | 732 old_status->active = FALSE; |
733 presence->active_status = status; | |
9949 | 734 } |
10754 | 735 else |
736 old_status = NULL; | |
9949 | 737 |
10204 | 738 notify_status_update(presence, old_status, status); |
739 } | |
740 | |
741 void | |
742 gaim_status_set_active(GaimStatus *status, gboolean active) | |
743 { | |
10754 | 744 gaim_status_set_active_with_attrs(status, active, NULL); |
10204 | 745 } |
746 | |
11249 | 747 /* |
748 * This used to parse the va_list directly, but now it creates a GList | |
749 * and passes it to gaim_status_set_active_with_attrs_list(). That | |
750 * function was created because accounts.c needs to pass a GList of | |
751 * attributes to the status API. | |
752 */ | |
10204 | 753 void |
754 gaim_status_set_active_with_attrs(GaimStatus *status, gboolean active, va_list args) | |
755 { | |
11249 | 756 GList *attrs = NULL; |
757 const gchar *id; | |
758 gpointer data; | |
759 | |
760 if (args != NULL) | |
761 { | |
762 while ((id = va_arg(args, const char *)) != NULL) | |
763 { | |
764 attrs = g_list_append(attrs, (char *)id); | |
765 data = va_arg(args, void *); | |
766 attrs = g_list_append(attrs, data); | |
767 } | |
768 } | |
769 gaim_status_set_active_with_attrs_list(status, active, attrs); | |
770 g_list_free(attrs); | |
771 } | |
772 | |
773 void | |
774 gaim_status_set_active_with_attrs_list(GaimStatus *status, gboolean active, | |
775 const GList *attrs) | |
776 { | |
10204 | 777 gboolean changed = FALSE; |
778 const gchar *id; | |
779 | |
10714 | 780 g_return_if_fail(status != NULL); |
781 | |
10204 | 782 if (!active && gaim_status_is_exclusive(status)) |
783 { | |
784 gaim_debug_error("status", | |
785 "Cannot deactivate an exclusive status (%s).\n", | |
786 gaim_status_get_id(status)); | |
787 return; | |
788 } | |
789 | |
790 if (status->active != active) | |
10738 | 791 { |
10204 | 792 changed = TRUE; |
10738 | 793 } |
10204 | 794 |
9949 | 795 status->active = active; |
6065 | 796 |
10204 | 797 /* Set any attributes */ |
11249 | 798 while (attrs) |
10204 | 799 { |
800 GaimValue *value; | |
11249 | 801 |
802 id = attrs->data; | |
803 attrs = attrs->next; | |
10204 | 804 value = gaim_status_get_attr_value(status, id); |
10713 | 805 if (value == NULL) |
806 { | |
807 gaim_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
10714 | 808 "not supported.\n", id, status->type->name); |
10713 | 809 /* Skip over the data and move on to the next attribute */ |
11249 | 810 attrs = attrs->next; |
10713 | 811 continue; |
812 } | |
813 | |
10204 | 814 if (value->type == GAIM_TYPE_STRING) |
815 { | |
11249 | 816 const gchar *string_data = attrs->data; |
817 attrs = attrs->next; | |
10204 | 818 if (((string_data == NULL) && (value->data.string_data == NULL)) || |
819 ((string_data != NULL) && (value->data.string_data != NULL) && | |
820 !strcmp(string_data, value->data.string_data))) | |
821 { | |
822 continue; | |
823 } | |
824 gaim_status_set_attr_string(status, id, string_data); | |
825 changed = TRUE; | |
826 } | |
827 else if (value->type == GAIM_TYPE_INT) | |
828 { | |
11586 | 829 int int_data = GPOINTER_TO_INT(attrs->data); |
11249 | 830 attrs = attrs->next; |
10204 | 831 if (int_data == value->data.int_data) |
832 continue; | |
833 gaim_status_set_attr_int(status, id, int_data); | |
834 changed = TRUE; | |
835 } | |
836 else if (value->type == GAIM_TYPE_BOOLEAN) | |
837 { | |
11586 | 838 gboolean boolean_data = GPOINTER_TO_INT(attrs->data); |
11249 | 839 attrs = attrs->next; |
10204 | 840 if (boolean_data == value->data.boolean_data) |
841 continue; | |
842 gaim_status_set_attr_int(status, id, boolean_data); | |
843 changed = TRUE; | |
844 } | |
845 else | |
846 { | |
847 /* We don't know what the data is--skip over it */ | |
11249 | 848 attrs = attrs->next; |
10204 | 849 } |
850 } | |
851 | |
852 if (!changed) | |
853 return; | |
854 status_has_changed(status); | |
9949 | 855 } |
856 | |
857 void | |
858 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
859 gboolean value) | |
860 { | |
861 GaimStatusType *status_type; | |
862 GaimValue *attr_value; | |
863 | |
864 g_return_if_fail(status != NULL); | |
865 g_return_if_fail(id != NULL); | |
866 | |
867 status_type = gaim_status_get_type(status); | |
868 | |
10197 | 869 /* Make sure this attribute exists and is the correct type. */ |
870 attr_value = gaim_status_get_attr_value(status, id); | |
871 g_return_if_fail(attr_value != NULL); | |
9949 | 872 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); |
873 | |
874 gaim_value_set_boolean(attr_value, value); | |
875 } | |
876 | |
877 void | |
878 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
879 { | |
880 GaimStatusType *status_type; | |
881 GaimValue *attr_value; | |
882 | |
883 g_return_if_fail(status != NULL); | |
884 g_return_if_fail(id != NULL); | |
885 | |
886 status_type = gaim_status_get_type(status); | |
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 GaimStatusType *status_type; | |
901 GaimValue *attr_value; | |
902 | |
903 g_return_if_fail(status != NULL); | |
904 g_return_if_fail(id != NULL); | |
905 | |
906 status_type = gaim_status_get_type(status); | |
907 | |
10197 | 908 /* Make sure this attribute exists and is the correct type. */ |
10196 | 909 attr_value = gaim_status_get_attr_value(status, id); |
10197 | 910 g_return_if_fail(attr_value != NULL); |
9949 | 911 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); |
912 | |
913 gaim_value_set_string(attr_value, value); | |
914 } | |
915 | |
916 GaimStatusType * | |
917 gaim_status_get_type(const GaimStatus *status) | |
918 { | |
919 g_return_val_if_fail(status != NULL, NULL); | |
920 | |
921 return status->type; | |
922 } | |
923 | |
924 GaimPresence * | |
925 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 926 { |
9949 | 927 g_return_val_if_fail(status != NULL, NULL); |
928 | |
929 return status->presence; | |
930 } | |
931 | |
932 const char * | |
933 gaim_status_get_id(const GaimStatus *status) | |
934 { | |
935 g_return_val_if_fail(status != NULL, NULL); | |
936 | |
937 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
938 } | |
939 | |
940 const char * | |
941 gaim_status_get_name(const GaimStatus *status) | |
942 { | |
943 g_return_val_if_fail(status != NULL, NULL); | |
944 | |
945 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
946 } | |
947 | |
948 gboolean | |
949 gaim_status_is_independent(const GaimStatus *status) | |
950 { | |
951 g_return_val_if_fail(status != NULL, FALSE); | |
952 | |
953 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
954 } | |
955 | |
956 gboolean | |
10067 | 957 gaim_status_is_exclusive(const GaimStatus *status) |
958 { | |
959 g_return_val_if_fail(status != NULL, FALSE); | |
960 | |
961 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
962 } | |
963 | |
964 gboolean | |
9949 | 965 gaim_status_is_available(const GaimStatus *status) |
966 { | |
967 g_return_val_if_fail(status != NULL, FALSE); | |
968 | |
969 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
970 } | |
6216 | 971 |
9949 | 972 gboolean |
973 gaim_status_is_active(const GaimStatus *status) | |
974 { | |
975 g_return_val_if_fail(status != NULL, FALSE); | |
976 | |
977 return status->active; | |
978 } | |
979 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
980 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
981 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
982 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
983 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
984 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
985 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
986 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
987 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
988 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
989 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
990 primitive != GAIM_STATUS_OFFLINE); |
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 |
9949 | 993 GaimValue * |
994 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
995 { | |
996 GaimStatusType *status_type; | |
997 GaimStatusAttr *attr; | |
998 | |
999 g_return_val_if_fail(status != NULL, NULL); | |
1000 g_return_val_if_fail(id != NULL, NULL); | |
1001 | |
1002 status_type = gaim_status_get_type(status); | |
1003 | |
1004 /* Make sure this attribute exists. */ | |
1005 attr = gaim_status_type_get_attr(status_type, id); | |
1006 g_return_val_if_fail(attr != NULL, NULL); | |
1007 | |
1008 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
1009 } | |
1010 | |
1011 gboolean | |
1012 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
1013 { | |
1014 const GaimValue *value; | |
1015 | |
1016 g_return_val_if_fail(status != NULL, FALSE); | |
1017 g_return_val_if_fail(id != NULL, FALSE); | |
1018 | |
1019 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
1020 return FALSE; | |
1021 | |
10197 | 1022 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_BOOLEAN, FALSE); |
9949 | 1023 |
1024 return gaim_value_get_boolean(value); | |
1025 } | |
1026 | |
1027 int | |
1028 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
1029 { | |
1030 const GaimValue *value; | |
1031 | |
10507 | 1032 g_return_val_if_fail(status != NULL, 0); |
1033 g_return_val_if_fail(id != NULL, 0); | |
9949 | 1034 |
1035 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10507 | 1036 return 0; |
9949 | 1037 |
1038 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
1039 | |
1040 return gaim_value_get_int(value); | |
1041 } | |
1042 | |
1043 const char * | |
1044 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
1045 { | |
1046 const GaimValue *value; | |
1047 | |
10507 | 1048 g_return_val_if_fail(status != NULL, NULL); |
1049 g_return_val_if_fail(id != NULL, NULL); | |
9949 | 1050 |
1051 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10504 | 1052 return NULL; |
9949 | 1053 |
1054 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
1055 | |
1056 return gaim_value_get_string(value); | |
1057 } | |
1058 | |
1059 gint | |
1060 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
1061 { | |
1062 GaimStatusType *type1, *type2; | |
1063 int score1 = 0, score2 = 0; | |
6065 | 1064 |
9949 | 1065 if ((status1 == NULL && status2 == NULL) || |
1066 (status1 == status2)) | |
1067 { | |
1068 return 0; | |
1069 } | |
1070 else if (status1 == NULL) | |
1071 return 1; | |
1072 else if (status2 == NULL) | |
1073 return -1; | |
1074 | |
1075 type1 = gaim_status_get_type(status1); | |
1076 type2 = gaim_status_get_type(status2); | |
1077 | |
1078 if (gaim_status_is_active(status1)) | |
1079 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
1080 | |
1081 if (gaim_status_is_active(status2)) | |
1082 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
1083 | |
1084 if (score1 > score2) | |
1085 return -1; | |
1086 else if (score1 < score2) | |
1087 return 1; | |
1088 | |
1089 return 0; | |
1090 } | |
1091 | |
1092 | |
1093 /************************************************************************** | |
1094 * GaimPresence API | |
1095 **************************************************************************/ | |
1096 GaimPresence * | |
1097 gaim_presence_new(GaimPresenceContext context) | |
1098 { | |
1099 GaimPresence *presence; | |
1100 | |
1101 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
1102 | |
1103 presence = g_new0(GaimPresence, 1); | |
11187 | 1104 GAIM_DBUS_REGISTER_POINTER(presence, GaimPresence); |
9949 | 1105 |
1106 presence->context = context; | |
1107 | |
1108 presence->status_table = | |
10009 | 1109 g_hash_table_new_full(g_str_hash, g_str_equal, |
1110 g_free, (GFreeFunc)gaim_status_destroy); | |
9949 | 1111 |
1112 return presence; | |
1113 } | |
1114 | |
1115 GaimPresence * | |
1116 gaim_presence_new_for_account(GaimAccount *account) | |
1117 { | |
10012 | 1118 GaimPresence *presence = NULL; |
9949 | 1119 g_return_val_if_fail(account != NULL, NULL); |
1120 | |
1121 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
1122 presence->u.account = account; | |
10006 | 1123 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 1124 |
1125 return presence; | |
1126 } | |
1127 | |
1128 GaimPresence * | |
1129 gaim_presence_new_for_conv(GaimConversation *conv) | |
1130 { | |
1131 GaimPresence *presence; | |
1132 | |
1133 g_return_val_if_fail(conv != NULL, NULL); | |
1134 | |
1135 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
1136 presence->u.chat.conv = conv; | |
10006 | 1137 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 1138 |
1139 return presence; | |
1140 } | |
6216 | 1141 |
9949 | 1142 GaimPresence * |
1143 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
1144 { | |
1145 GaimPresence *presence; | |
1146 GaimStatusBuddyKey *key; | |
10006 | 1147 GaimAccount *account; |
9949 | 1148 |
1149 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 1150 account = buddy->account; |
9949 | 1151 |
1152 key = g_new0(GaimStatusBuddyKey, 1); | |
1153 key->account = buddy->account; | |
1154 key->name = g_strdup(buddy->name); | |
10006 | 1155 |
1156 presence = g_hash_table_lookup(buddy_presences, key); | |
1157 if (presence == NULL) | |
9949 | 1158 { |
1159 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
1160 | |
1161 presence->u.buddy.name = g_strdup(buddy->name); | |
1162 presence->u.buddy.account = buddy->account; | |
10006 | 1163 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 1164 |
1165 g_hash_table_insert(buddy_presences, key, presence); | |
1166 } | |
1167 else | |
1168 { | |
1169 g_free(key->name); | |
1170 g_free(key); | |
1171 } | |
1172 | |
1173 presence->u.buddy.ref_count++; | |
1174 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
1175 buddy); | |
1176 | |
1177 return presence; | |
1178 } | |
1179 | |
1180 void | |
1181 gaim_presence_destroy(GaimPresence *presence) | |
1182 { | |
1183 g_return_if_fail(presence != NULL); | |
6216 | 1184 |
9949 | 1185 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1186 { | |
1187 GaimStatusBuddyKey key; | |
1188 | |
10077 | 1189 if(presence->u.buddy.ref_count != 0) |
1190 return; | |
9949 | 1191 |
1192 key.account = presence->u.buddy.account; | |
1193 key.name = presence->u.buddy.name; | |
1194 | |
1195 g_hash_table_remove(buddy_presences, &key); | |
1196 | |
1197 if (presence->u.buddy.name != NULL) | |
1198 g_free(presence->u.buddy.name); | |
1199 } | |
1200 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1201 { | |
1202 if (presence->u.chat.user != NULL) | |
1203 g_free(presence->u.chat.user); | |
1204 } | |
1205 | |
1206 if (presence->statuses != NULL) | |
1207 g_list_free(presence->statuses); | |
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 { | |
1301 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1302 | |
1303 if (!old_idle && idle) | |
1304 { | |
1305 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle", buddy); | |
1306 | |
1307 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1308 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1309 { | |
1310 GaimLog *log = gaim_account_get_log(buddy->account); | |
1311 char *tmp = g_strdup_printf(_("%s became idle"), | |
1312 gaim_buddy_get_alias(buddy)); | |
1313 | |
1314 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1315 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1316 g_free(tmp); | |
1317 } | |
1318 } | |
1319 else if (old_idle && !idle) | |
1320 { | |
1321 gaim_signal_emit(gaim_blist_get_handle(), "buddy-unidle", buddy); | |
1322 | |
1323 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1324 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1325 { | |
1326 GaimLog *log = gaim_account_get_log(buddy->account); | |
1327 char *tmp = g_strdup_printf(_("%s became unidle"), | |
1328 gaim_buddy_get_alias(buddy)); | |
1329 | |
1330 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1331 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1332 g_free(tmp); | |
1333 } | |
1334 } | |
1335 | |
10378 | 1336 gaim_contact_invalidate_priority_buddy(gaim_buddy_get_contact(buddy)); |
9949 | 1337 |
1338 if (ops != NULL && ops->update != NULL) | |
1339 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
1340 } | |
1341 | |
1342 void | |
1343 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
1344 { | |
1345 gboolean old_idle; | |
1346 | |
1347 g_return_if_fail(presence != NULL); | |
1348 | |
1349 if (presence->idle == idle && presence->idle_time == idle_time) | |
1350 return; | |
1351 | |
1352 old_idle = presence->idle; | |
1353 presence->idle = idle; | |
1354 presence->idle_time = (idle ? idle_time : 0); | |
1355 | |
1356 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1357 { | |
1358 const GList *l; | |
1359 time_t current_time = time(NULL); | |
1360 | |
1361 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
1362 { | |
1363 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
1364 old_idle, idle); | |
1365 } | |
1366 } | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1367 else if(gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_ACCOUNT) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1368 { |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1369 GaimConnection *gc = |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1370 gaim_account_get_connection(gaim_presence_get_account(presence)); |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1371 GaimPluginProtocolInfo *prpl_info = NULL; |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1372 |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1373 if (gc != NULL && gc->prpl != NULL) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1374 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1375 |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1376 if (prpl_info && g_list_find(gaim_connections_get_all(), gc) && |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1377 prpl_info->set_idle) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1378 prpl_info->set_idle(gc, time(NULL) - idle_time); |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1379 } |
9949 | 1380 } |
1381 | |
1382 void | |
10006 | 1383 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
1384 { | |
1385 g_return_if_fail(presence != NULL); | |
1386 | |
1387 if (presence->login_time == login_time) | |
1388 return; | |
1389 | |
1390 presence->login_time = login_time; | |
1391 } | |
1392 | |
9949 | 1393 GaimPresenceContext |
1394 gaim_presence_get_context(const GaimPresence *presence) | |
1395 { | |
1396 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
1397 | |
1398 return presence->context; | |
1399 } | |
1400 | |
1401 GaimAccount * | |
1402 gaim_presence_get_account(const GaimPresence *presence) | |
1403 { | |
1404 GaimPresenceContext context; | |
1405 | |
1406 g_return_val_if_fail(presence != NULL, NULL); | |
1407 | |
1408 context = gaim_presence_get_context(presence); | |
1409 | |
1410 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
1411 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1412 | |
1413 return presence->u.account; | |
1414 } | |
1415 | |
1416 GaimConversation * | |
1417 gaim_presence_get_conversation(const GaimPresence *presence) | |
1418 { | |
1419 g_return_val_if_fail(presence != NULL, NULL); | |
1420 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1421 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1422 | |
1423 return presence->u.chat.conv; | |
1424 } | |
1425 | |
1426 const char * | |
1427 gaim_presence_get_chat_user(const GaimPresence *presence) | |
1428 { | |
1429 g_return_val_if_fail(presence != NULL, NULL); | |
1430 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1431 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1432 | |
1433 return presence->u.chat.user; | |
1434 } | |
1435 | |
1436 const GList * | |
1437 gaim_presence_get_buddies(const GaimPresence *presence) | |
1438 { | |
1439 g_return_val_if_fail(presence != NULL, NULL); | |
1440 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1441 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1442 | |
1443 return presence->u.buddy.buddies; | |
1444 } | |
1445 | |
1446 const GList * | |
1447 gaim_presence_get_statuses(const GaimPresence *presence) | |
1448 { | |
1449 g_return_val_if_fail(presence != NULL, NULL); | |
1450 | |
1451 return presence->statuses; | |
1452 } | |
1453 | |
1454 GaimStatus * | |
1455 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
1456 { | |
1457 GaimStatus *status; | |
10006 | 1458 const GList *l = NULL; |
9949 | 1459 |
1460 g_return_val_if_fail(presence != NULL, NULL); | |
1461 g_return_val_if_fail(status_id != NULL, NULL); | |
1462 | |
10006 | 1463 /* What's the purpose of this hash table? */ |
10012 | 1464 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
10006 | 1465 status_id); |
10012 | 1466 |
10006 | 1467 if (status == NULL) { |
10012 | 1468 for (l = gaim_presence_get_statuses(presence); |
10006 | 1469 l != NULL && status == NULL; l = l->next) |
1470 { | |
1471 GaimStatus *temp_status = l->data; | |
10012 | 1472 |
10006 | 1473 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
1474 status = temp_status; | |
1475 } | |
1476 | |
1477 if (status != NULL) | |
1478 g_hash_table_insert(presence->status_table, | |
1479 g_strdup(gaim_status_get_id(status)), status); | |
10012 | 1480 } |
9949 | 1481 |
1482 return status; | |
1483 } | |
1484 | |
1485 GaimStatus * | |
1486 gaim_presence_get_active_status(const GaimPresence *presence) | |
1487 { | |
1488 g_return_val_if_fail(presence != NULL, NULL); | |
1489 | |
1490 return presence->active_status; | |
1491 } | |
1492 | |
1493 gboolean | |
1494 gaim_presence_is_available(const GaimPresence *presence) | |
1495 { | |
1496 GaimStatus *status; | |
1497 | |
1498 g_return_val_if_fail(presence != NULL, FALSE); | |
1499 | |
1500 status = gaim_presence_get_active_status(presence); | |
1501 | |
1502 return ((status != NULL && gaim_status_is_available(status)) && | |
1503 !gaim_presence_is_idle(presence)); | |
1504 } | |
1505 | |
1506 gboolean | |
1507 gaim_presence_is_online(const GaimPresence *presence) | |
1508 { | |
1509 GaimStatus *status; | |
1510 | |
1511 g_return_val_if_fail(presence != NULL, FALSE); | |
1512 | |
1513 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
1514 return FALSE; | |
1515 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1516 return gaim_status_is_online(status); |
9949 | 1517 } |
1518 | |
1519 gboolean | |
1520 gaim_presence_is_status_active(const GaimPresence *presence, | |
1521 const char *status_id) | |
1522 { | |
1523 GaimStatus *status; | |
1524 | |
1525 g_return_val_if_fail(presence != NULL, FALSE); | |
1526 g_return_val_if_fail(status_id != NULL, FALSE); | |
1527 | |
1528 status = gaim_presence_get_status(presence, status_id); | |
1529 | |
1530 return (status != NULL && gaim_status_is_active(status)); | |
1531 } | |
1532 | |
1533 gboolean | |
1534 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
1535 GaimStatusPrimitive primitive) | |
1536 { | |
1537 GaimStatus *status; | |
1538 GaimStatusType *status_type; | |
1539 | |
1540 g_return_val_if_fail(presence != NULL, FALSE); | |
1541 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
1542 | |
1543 status = gaim_presence_get_active_status(presence); | |
1544 status_type = gaim_status_get_type(status); | |
1545 | |
1546 if (gaim_status_type_get_primitive(status_type) == primitive) | |
1547 return TRUE; | |
6065 | 1548 |
1549 return FALSE; | |
1550 } | |
1551 | |
9949 | 1552 gboolean |
1553 gaim_presence_is_idle(const GaimPresence *presence) | |
6065 | 1554 { |
9949 | 1555 g_return_val_if_fail(presence != NULL, FALSE); |
1556 | |
11634 | 1557 return gaim_presence_is_online(presence) && presence->idle; |
6065 | 1558 } |
1559 | |
9949 | 1560 time_t |
1561 gaim_presence_get_idle_time(const GaimPresence *presence) | |
6065 | 1562 { |
9949 | 1563 g_return_val_if_fail(presence != NULL, 0); |
6065 | 1564 |
9949 | 1565 return presence->idle_time; |
1566 } | |
6065 | 1567 |
10567 | 1568 time_t |
1569 gaim_presence_get_login_time(const GaimPresence *presence) | |
1570 { | |
1571 g_return_val_if_fail(presence != NULL, 0); | |
1572 | |
1573 return presence->login_time; | |
1574 } | |
1575 | |
9949 | 1576 gint |
1577 gaim_presence_compare(const GaimPresence *presence1, | |
1578 const GaimPresence *presence2) | |
6065 | 1579 { |
9949 | 1580 gboolean idle1, idle2; |
10860 | 1581 time_t idle_time_1, idle_time_2; |
9949 | 1582 int score1 = 0, score2 = 0; |
1583 const GList *l; | |
6065 | 1584 |
9949 | 1585 if ((presence1 == NULL && presence2 == NULL) || (presence1 == presence2)) |
1586 return 0; | |
1587 else if (presence1 == NULL) | |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1588 return 1; |
9949 | 1589 else if (presence2 == NULL) |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1590 return -1; |
6065 | 1591 |
9949 | 1592 /* Compute the score of the first set of statuses. */ |
1593 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1594 { | |
1595 GaimStatus *status = (GaimStatus *)l->data; | |
1596 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1597 |
9949 | 1598 if (gaim_status_is_active(status)) |
1599 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1600 } |
1601 | |
9949 | 1602 /* Compute the score of the second set of statuses. */ |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1603 for (l = gaim_presence_get_statuses(presence2); l != NULL; l = l->next) |
9949 | 1604 { |
1605 GaimStatus *status = (GaimStatus *)l->data; | |
1606 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1607 |
9949 | 1608 if (gaim_status_is_active(status)) |
1609 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1610 } |
1611 | |
9949 | 1612 idle1 = gaim_presence_is_idle(presence1); |
1613 idle2 = gaim_presence_is_idle(presence2); | |
6065 | 1614 |
9949 | 1615 if (idle1) |
1616 score1 += primitive_scores[SCORE_IDLE]; | |
6065 | 1617 |
9949 | 1618 if (idle2) |
1619 score2 += primitive_scores[SCORE_IDLE]; | |
6065 | 1620 |
10860 | 1621 idle_time_1 = time(NULL) - gaim_presence_get_idle_time(presence1); |
1622 idle_time_2 = time(NULL) - gaim_presence_get_idle_time(presence2); | |
6065 | 1623 |
9949 | 1624 if (idle_time_1 > idle_time_2) |
1625 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
1626 else if (idle_time_1 < idle_time_2) | |
1627 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
6065 | 1628 |
9949 | 1629 if (score1 < score2) |
1630 return 1; | |
1631 else if (score1 > score2) | |
1632 return -1; | |
1633 | |
1634 return 0; | |
1635 } | |
1636 | |
6065 | 1637 |
9949 | 1638 /************************************************************************** |
1639 * Status subsystem | |
1640 **************************************************************************/ | |
1641 static void | |
1642 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
1643 gpointer data) | |
1644 { | |
1645 int index = GPOINTER_TO_INT(data); | |
6065 | 1646 |
9949 | 1647 primitive_scores[index] = GPOINTER_TO_INT(value); |
6065 | 1648 } |
1649 | |
10519 | 1650 static guint |
10006 | 1651 gaim_buddy_presences_hash(gconstpointer key) |
1652 { | |
10012 | 1653 const GaimStatusBuddyKey *me = key; |
1654 guint ret; | |
1655 char *str; | |
1656 | |
1657 str = g_strdup_printf("%p%s", me->account, me->name); | |
1658 ret = g_str_hash(str); | |
1659 g_free(str); | |
1660 | |
1661 return ret; | |
10006 | 1662 } |
1663 | |
10519 | 1664 static gboolean |
10006 | 1665 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
1666 { | |
1667 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
1668 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
1669 | |
10012 | 1670 if(key_a->account == key_b->account && |
1671 !strcmp(key_a->name, key_b->name)) | |
10006 | 1672 return TRUE; |
1673 else | |
1674 return FALSE; | |
1675 } | |
1676 | |
10519 | 1677 static void |
1678 gaim_buddy_presences_key_free(gpointer a) | |
1679 { | |
1680 GaimStatusBuddyKey *key = (GaimStatusBuddyKey *)a; | |
1681 g_free(key->name); | |
1682 g_free(key); | |
1683 } | |
1684 | |
10087 | 1685 void * |
10418 | 1686 gaim_status_get_handle(void) { |
10087 | 1687 static int handle; |
1688 | |
1689 return &handle; | |
1690 } | |
1691 | |
9949 | 1692 void |
10418 | 1693 gaim_status_init(void) |
6065 | 1694 { |
10418 | 1695 void *handle = gaim_status_get_handle; |
10087 | 1696 |
9949 | 1697 gaim_prefs_add_none("/core/status"); |
1698 gaim_prefs_add_none("/core/status/scores"); | |
6065 | 1699 |
9949 | 1700 gaim_prefs_add_int("/core/status/scores/offline", |
1701 primitive_scores[GAIM_STATUS_OFFLINE]); | |
1702 gaim_prefs_add_int("/core/status/scores/available", | |
1703 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
1704 gaim_prefs_add_int("/core/status/scores/hidden", | |
1705 primitive_scores[GAIM_STATUS_HIDDEN]); | |
1706 gaim_prefs_add_int("/core/status/scores/away", | |
1707 primitive_scores[GAIM_STATUS_AWAY]); | |
1708 gaim_prefs_add_int("/core/status/scores/extended_away", | |
1709 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
1710 gaim_prefs_add_int("/core/status/scores/idle", | |
1711 primitive_scores[SCORE_IDLE]); | |
6065 | 1712 |
10087 | 1713 gaim_prefs_connect_callback(handle, "/core/status/scores/offline", |
9949 | 1714 score_pref_changed_cb, |
1715 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
10087 | 1716 gaim_prefs_connect_callback(handle, "/core/status/scores/available", |
9949 | 1717 score_pref_changed_cb, |
1718 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
10087 | 1719 gaim_prefs_connect_callback(handle, "/core/status/scores/hidden", |
9949 | 1720 score_pref_changed_cb, |
1721 GINT_TO_POINTER(GAIM_STATUS_HIDDEN)); | |
10087 | 1722 gaim_prefs_connect_callback(handle, "/core/status/scores/away", |
9949 | 1723 score_pref_changed_cb, |
1724 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
10087 | 1725 gaim_prefs_connect_callback(handle, "/core/status/scores/extended_away", |
9949 | 1726 score_pref_changed_cb, |
1727 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
10087 | 1728 gaim_prefs_connect_callback(handle, "/core/status/scores/idle", |
9949 | 1729 score_pref_changed_cb, |
1730 GINT_TO_POINTER(SCORE_IDLE)); | |
10006 | 1731 |
10519 | 1732 buddy_presences = g_hash_table_new_full(gaim_buddy_presences_hash, |
1733 gaim_buddy_presences_equal, | |
1734 gaim_buddy_presences_key_free, NULL); | |
9949 | 1735 } |
6065 | 1736 |
9949 | 1737 void |
10418 | 1738 gaim_status_uninit(void) |
9949 | 1739 { |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1740 if (buddy_presences != NULL) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1741 { |
10077 | 1742 g_hash_table_destroy(buddy_presences); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1743 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1744 buddy_presences = NULL; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1745 } |
9949 | 1746 } |