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