Mercurial > pidgin.yaz
annotate src/status.c @ 10040:81059dce3aed
[gaim-migrate @ 10999]
" Post all three of these to the sf patch tracker as
three separate patches and assign the buddy list
changes and oscar changes to me, and the
gaim_status_is_online() changes to Luke. And in the
one assigned to Luke, ask him if he could pretty please
with sugar on top check through it quickly and
commit it if it looks sensible?
--KingAnt
This adds gaim_status_is_online so that we can check
statuses as well as presences for online status. It
also changes gaim_presence_is_online to use the new
function." --Dave West
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sat, 18 Sep 2004 23:17:38 +0000 |
parents | f1f239fa8973 |
children | eaec201b2688 |
rev | line source |
---|---|
9944 | 1 /** |
2 * @file status.h Status API | |
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" |
28 #include "debug.h" | |
29 #include "prefs.h" | |
6065 | 30 #include "status.h" |
31 #include "util.h" | |
32 | |
9949 | 33 /** |
34 * A type of status. | |
35 */ | |
36 struct _GaimStatusType | |
37 { | |
38 GaimStatusPrimitive primitive; | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
39 |
9949 | 40 char *id; |
41 char *name; | |
42 char *primary_attr_id; | |
43 | |
44 gboolean saveable; | |
45 gboolean user_settable; | |
46 gboolean independent; | |
47 | |
48 GList *attrs; | |
49 }; | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
50 |
9949 | 51 /** |
52 * A status attribute. | |
53 */ | |
54 struct _GaimStatusAttr | |
55 { | |
56 char *id; | |
57 char *name; | |
58 GaimValue *value_type; | |
59 }; | |
6065 | 60 |
9949 | 61 /** |
62 * A list of statuses. | |
63 */ | |
64 struct _GaimPresence | |
65 { | |
66 GaimPresenceContext context; | |
67 | |
68 gboolean idle; | |
69 time_t idle_time; | |
10006 | 70 time_t login_time; |
9949 | 71 |
72 unsigned int warning_level; | |
6065 | 73 |
9949 | 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 | |
124 #if 0 | |
125 static GList *stored_statuses = NULL; | |
126 | |
127 /* | |
128 * XXX This stuff should be removed in a few versions. It stores the | |
129 * old v1 status stuff so we can write it later. We don't write out | |
130 * the new status stuff, though. These should all die soon, as the | |
131 * old status.xml was created before the new status system's design | |
132 * was created. | |
133 * | |
134 * -- ChipX86 | |
135 */ | |
136 typedef struct | |
137 { | |
138 char *name; | |
139 char *state; | |
140 char *message; | |
141 | |
142 } GaimStatusV1Info; | |
143 | |
144 static GList *v1_statuses = NULL; | |
145 #endif | |
146 | |
147 | |
148 static int primitive_scores[] = | |
149 { | |
150 0, /* unset */ | |
151 -500, /* offline */ | |
152 0, /* online */ | |
153 100, /* available */ | |
154 -75, /* unavailable */ | |
155 -50, /* hidden */ | |
156 -100, /* away */ | |
157 -200 /* extended away */ | |
158 -10, /* idle, special case. */ | |
159 -5 /* idle time, special case. */ | |
160 }; | |
161 | |
162 static GHashTable *buddy_presences = NULL; | |
163 | |
164 #define SCORE_IDLE 5 | |
165 #define SCORE_IDLE_TIME 6 | |
166 | |
167 /************************************************************************** | |
168 * GaimStatusType API | |
169 **************************************************************************/ | |
170 GaimStatusType * | |
171 gaim_status_type_new_full(GaimStatusPrimitive primitive, const char *id, | |
10009 | 172 const char *name, gboolean saveable, |
173 gboolean user_settable, gboolean independent) | |
9949 | 174 { |
175 GaimStatusType *status_type; | |
176 | |
177 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
178 g_return_val_if_fail(id != NULL, NULL); | |
179 g_return_val_if_fail(name != NULL, NULL); | |
180 | |
181 status_type = g_new0(GaimStatusType, 1); | |
182 | |
183 status_type->primitive = primitive; | |
184 status_type->id = g_strdup(id); | |
185 status_type->name = g_strdup(name); | |
186 status_type->saveable = saveable; | |
187 status_type->user_settable = user_settable; | |
188 status_type->independent = independent; | |
189 | |
190 return status_type; | |
191 } | |
192 | |
193 GaimStatusType * | |
194 gaim_status_type_new(GaimStatusPrimitive primitive, const char *id, | |
10009 | 195 const char *name, gboolean user_settable) |
9949 | 196 { |
197 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
198 g_return_val_if_fail(id != NULL, NULL); | |
199 g_return_val_if_fail(name != NULL, NULL); | |
200 | |
201 return gaim_status_type_new_full(primitive, id, name, FALSE, | |
202 user_settable, FALSE); | |
203 } | |
204 | |
205 GaimStatusType * | |
206 gaim_status_type_new_with_attrs(GaimStatusPrimitive primitive, | |
207 const char *id, const char *name, | |
208 gboolean saveable, gboolean user_settable, | |
209 gboolean independent, const char *attr_id, | |
210 const char *attr_name, GaimValue *attr_value, | |
211 ...) | |
212 { | |
213 GaimStatusType *status_type; | |
214 va_list args; | |
215 | |
216 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
217 g_return_val_if_fail(id != NULL, NULL); | |
218 g_return_val_if_fail(name != NULL, NULL); | |
10012 | 219 g_return_val_if_fail(attr_id != NULL, NULL); |
9949 | 220 g_return_val_if_fail(attr_name != NULL, NULL); |
221 g_return_val_if_fail(attr_value != NULL, NULL); | |
222 | |
223 status_type = gaim_status_type_new_full(primitive, id, name, saveable, | |
224 user_settable, independent); | |
225 | |
10010 | 226 /* Add the first attribute */ |
9949 | 227 gaim_status_type_add_attr(status_type, attr_id, attr_name, attr_value); |
228 | |
229 va_start(args, attr_value); | |
230 gaim_status_type_add_attrs_vargs(status_type, args); | |
231 va_end(args); | |
232 | |
233 return status_type; | |
234 } | |
235 | |
236 void | |
237 gaim_status_type_destroy(GaimStatusType *status_type) | |
238 { | |
239 GList *l; | |
240 | |
241 g_return_if_fail(status_type != NULL); | |
242 | |
243 g_free(status_type->id); | |
244 g_free(status_type->name); | |
245 | |
246 if (status_type->primary_attr_id != NULL) | |
247 g_free(status_type->primary_attr_id); | |
248 | |
249 if (status_type->attrs != NULL) | |
250 { | |
251 for (l = status_type->attrs; l != NULL; l = l->next) | |
252 gaim_status_attr_destroy((GaimStatusAttr *)l->data); | |
253 | |
254 g_list_free(status_type->attrs); | |
255 } | |
256 | |
257 g_free(status_type); | |
258 } | |
259 | |
260 void | |
261 gaim_status_type_set_primary_attr(GaimStatusType *status_type, const char *id) | |
262 { | |
263 g_return_if_fail(status_type != NULL); | |
264 | |
265 if (status_type->primary_attr_id != NULL) | |
266 g_free(status_type->primary_attr_id); | |
267 | |
268 status_type->primary_attr_id = (id == NULL ? NULL : g_strdup(id)); | |
269 } | |
270 | |
271 void | |
272 gaim_status_type_add_attr(GaimStatusType *status_type, const char *id,\ | |
273 const char *name, GaimValue *value) | |
274 { | |
275 GaimStatusAttr *attr; | |
276 | |
277 g_return_if_fail(status_type != NULL); | |
278 g_return_if_fail(id != NULL); | |
279 g_return_if_fail(name != NULL); | |
280 g_return_if_fail(value != NULL); | |
281 | |
282 attr = gaim_status_attr_new(id, name, value); | |
283 | |
284 status_type->attrs = g_list_append(status_type->attrs, attr); | |
285 } | |
286 | |
287 void | |
288 gaim_status_type_add_attrs_vargs(GaimStatusType *status_type, va_list args) | |
289 { | |
290 const char *id, *name; | |
291 GaimValue *value; | |
292 | |
293 g_return_if_fail(status_type != NULL); | |
294 | |
295 while ((id = va_arg(args, const char *)) != NULL) | |
296 { | |
297 name = va_arg(args, const char *); | |
298 g_return_if_fail(name != NULL); | |
299 | |
300 value = va_arg(args, GaimValue *); | |
301 g_return_if_fail(value != NULL); | |
6065 | 302 |
9949 | 303 gaim_status_type_add_attr(status_type, id, name, value); |
304 } | |
305 } | |
306 | |
10010 | 307 void |
308 gaim_status_type_add_attrs(GaimStatusType *status_type, const char *id, | |
309 const char *name, GaimValue *value, ...) | |
310 { | |
311 va_list args; | |
312 | |
313 g_return_if_fail(status_type != NULL); | |
314 g_return_if_fail(id != NULL); | |
315 g_return_if_fail(name != NULL); | |
316 g_return_if_fail(value != NULL); | |
317 | |
318 /* Add the first attribute */ | |
319 gaim_status_type_add_attr(status_type, id, name, value); | |
320 | |
321 va_start(args, value); | |
322 gaim_status_type_add_attrs_vargs(status_type, args); | |
323 va_end(args); | |
324 } | |
325 | |
9949 | 326 GaimStatusPrimitive |
327 gaim_status_type_get_primitive(const GaimStatusType *status_type) | |
328 { | |
329 g_return_val_if_fail(status_type != NULL, GAIM_STATUS_UNSET); | |
330 | |
331 return status_type->primitive; | |
332 } | |
333 | |
334 const char * | |
335 gaim_status_type_get_id(const GaimStatusType *status_type) | |
336 { | |
337 g_return_val_if_fail(status_type != NULL, NULL); | |
338 | |
339 return status_type->id; | |
340 } | |
341 | |
342 const char * | |
343 gaim_status_type_get_name(const GaimStatusType *status_type) | |
344 { | |
345 g_return_val_if_fail(status_type != NULL, NULL); | |
346 | |
347 return status_type->name; | |
348 } | |
349 | |
350 gboolean | |
351 gaim_status_type_is_saveable(const GaimStatusType *status_type) | |
352 { | |
353 g_return_val_if_fail(status_type != NULL, FALSE); | |
354 | |
355 return status_type->saveable; | |
356 } | |
357 | |
358 gboolean | |
359 gaim_status_type_is_user_settable(const GaimStatusType *status_type) | |
360 { | |
361 g_return_val_if_fail(status_type != NULL, FALSE); | |
362 | |
363 return status_type->user_settable; | |
364 } | |
365 | |
366 gboolean | |
367 gaim_status_type_is_independent(const GaimStatusType *status_type) | |
368 { | |
369 g_return_val_if_fail(status_type != NULL, FALSE); | |
370 | |
371 return status_type->independent; | |
372 } | |
373 | |
374 gboolean | |
375 gaim_status_type_is_available(const GaimStatusType *status_type) | |
376 { | |
377 GaimStatusPrimitive primitive; | |
378 | |
379 g_return_val_if_fail(status_type != NULL, FALSE); | |
380 | |
381 primitive = gaim_status_type_get_primitive(status_type); | |
382 | |
383 return (primitive == GAIM_STATUS_AVAILABLE || | |
384 primitive == GAIM_STATUS_HIDDEN); | |
385 } | |
386 | |
387 const char * | |
388 gaim_status_type_get_primary_attr(const GaimStatusType *status_type) | |
389 { | |
390 g_return_val_if_fail(status_type != NULL, NULL); | |
391 | |
392 return status_type->primary_attr_id; | |
393 } | |
394 | |
395 GaimStatusAttr * | |
396 gaim_status_type_get_attr(const GaimStatusType *status_type, const char *id) | |
397 { | |
398 GList *l; | |
399 | |
400 g_return_val_if_fail(status_type != NULL, NULL); | |
401 g_return_val_if_fail(id != NULL, NULL); | |
402 | |
403 for (l = status_type->attrs; l != NULL; l = l->next) | |
404 { | |
405 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
406 | |
407 if (!strcmp(gaim_status_attr_get_id(attr), id)) | |
408 return attr; | |
409 } | |
410 | |
411 return NULL; | |
412 } | |
413 | |
414 const GList * | |
415 gaim_status_type_get_attrs(const GaimStatusType *status_type) | |
416 { | |
417 g_return_val_if_fail(status_type != NULL, NULL); | |
418 | |
419 return status_type->attrs; | |
420 } | |
421 | |
422 | |
423 /************************************************************************** | |
424 * GaimStatusAttr API | |
425 **************************************************************************/ | |
426 GaimStatusAttr * | |
427 gaim_status_attr_new(const char *id, const char *name, GaimValue *value_type) | |
428 { | |
429 GaimStatusAttr *attr; | |
430 | |
431 g_return_val_if_fail(id != NULL, NULL); | |
432 g_return_val_if_fail(name != NULL, NULL); | |
433 g_return_val_if_fail(value_type != NULL, NULL); | |
434 | |
435 attr = g_new0(GaimStatusAttr, 1); | |
436 | |
437 attr->id = g_strdup(id); | |
438 attr->name = g_strdup(name); | |
439 attr->value_type = value_type; | |
440 | |
441 return attr; | |
442 } | |
443 | |
444 void | |
445 gaim_status_attr_destroy(GaimStatusAttr *attr) | |
446 { | |
447 g_return_if_fail(attr != NULL); | |
448 | |
449 g_free(attr->id); | |
450 g_free(attr->name); | |
451 | |
452 gaim_value_destroy(attr->value_type); | |
453 | |
454 g_free(attr); | |
455 } | |
456 | |
457 const char * | |
458 gaim_status_attr_get_id(const GaimStatusAttr *attr) | |
459 { | |
460 g_return_val_if_fail(attr != NULL, NULL); | |
461 | |
462 return attr->id; | |
463 } | |
464 | |
465 const char * | |
466 gaim_status_attr_get_name(const GaimStatusAttr *attr) | |
467 { | |
468 g_return_val_if_fail(attr != NULL, NULL); | |
469 | |
470 return attr->name; | |
471 } | |
472 | |
473 GaimValue * | |
474 gaim_status_attr_get_value_type(const GaimStatusAttr *attr) | |
475 { | |
476 g_return_val_if_fail(attr != NULL, NULL); | |
477 | |
478 return attr->value_type; | |
479 } | |
480 | |
481 | |
482 /************************************************************************** | |
483 * GaimStatus API | |
484 **************************************************************************/ | |
485 GaimStatus * | |
486 gaim_status_new(GaimStatusType *status_type, GaimPresence *presence) | |
487 { | |
488 GaimStatus *status; | |
489 const GList *l; | |
490 | |
491 g_return_val_if_fail(status_type != NULL, NULL); | |
492 g_return_val_if_fail(presence != NULL, NULL); | |
493 | |
494 status = g_new0(GaimStatus, 1); | |
495 | |
496 status->type = status_type; | |
497 status->presence = presence; | |
498 | |
499 status->attr_values = | |
500 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
501 (GDestroyNotify)gaim_value_destroy); | |
502 | |
503 for (l = gaim_status_type_get_attrs(status_type); l != NULL; l = l->next) | |
504 { | |
505 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
506 GaimValue *value = gaim_status_attr_get_value_type(attr); | |
507 GaimValue *new_value = gaim_value_dup(value); | |
508 | |
509 g_hash_table_insert(status->attr_values, | |
510 g_strdup(gaim_status_attr_get_id(attr)), new_value); | |
511 } | |
512 | |
513 return status; | |
514 } | |
515 | |
516 void | |
517 gaim_status_destroy(GaimStatus *status) | |
518 { | |
519 g_return_if_fail(status != NULL); | |
520 | |
521 gaim_status_set_active(status, FALSE); | |
522 | |
523 g_hash_table_destroy(status->attr_values); | |
524 | |
525 g_free(status); | |
526 } | |
6065 | 527 |
528 static void | |
9949 | 529 notify_buddy_status_update(GaimBuddy *buddy, GaimPresence *presence, |
530 GaimStatus *old_status, GaimStatus *new_status) | |
531 { | |
532 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | |
533 | |
534 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
535 gaim_prefs_get_bool("/core/logging/log_away_state")) | |
536 { | |
537 time_t current_time = time(NULL); | |
538 const char *buddy_alias = gaim_buddy_get_alias(buddy); | |
539 char *tmp = NULL; | |
540 | |
541 if (!gaim_status_is_available(old_status) && | |
542 gaim_status_is_available(new_status)) | |
543 { | |
544 tmp = g_strdup_printf(_("%s came back"), buddy_alias); | |
545 } | |
546 else if (gaim_status_is_available(old_status) && | |
547 !gaim_status_is_available(new_status)) | |
548 { | |
549 tmp = g_strdup_printf(_("%s went away"), buddy_alias); | |
550 } | |
551 | |
552 if (tmp != NULL) | |
553 { | |
554 GaimLog *log = gaim_account_get_log(buddy->account); | |
555 | |
556 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, | |
557 current_time, tmp); | |
558 g_free(tmp); | |
559 } | |
560 } | |
561 | |
10012 | 562 |
563 | |
564 if (ops != NULL && ops->update != NULL) | |
565 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 566 } |
567 | |
568 static void | |
569 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
570 GaimStatus *new_status) | |
6065 | 571 { |
9949 | 572 GaimPresenceContext context = gaim_presence_get_context(presence); |
573 | |
10006 | 574 gaim_debug_info("notify_status_update", "Context is %d\n", context); |
575 | |
9949 | 576 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) |
577 { | |
578 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); | |
579 | |
580 if (ops != NULL && ops->status_changed != NULL) | |
581 { | |
582 ops->status_changed(gaim_presence_get_account(presence), | |
583 new_status); | |
584 } | |
585 } | |
586 else if (context == GAIM_PRESENCE_CONTEXT_CONV) | |
587 { | |
588 /* TODO */ | |
589 #if 0 | |
590 GaimConversationUiOps *ops; | |
591 GaimConversation *conv; | |
592 | |
593 conv = gaim_status_get_conversation(new_status); | |
594 #endif | |
595 } | |
596 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
597 { | |
598 const GList *l; | |
599 | |
600 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
601 { | |
602 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
603 old_status, new_status); | |
604 } | |
605 } | |
606 } | |
607 | |
608 void | |
609 gaim_status_set_active(GaimStatus *status, gboolean active) | |
610 { | |
611 GaimStatusType *status_type; | |
612 GaimPresence *presence; | |
613 GaimStatus *old_status; | |
614 | |
615 g_return_if_fail(status != NULL); | |
616 | |
617 if (status->active == active) | |
618 return; | |
619 | |
620 status_type = gaim_status_get_type(status); | |
6065 | 621 |
10006 | 622 if (!active && !gaim_status_type_is_independent(status_type)) |
9949 | 623 { |
624 gaim_debug(GAIM_DEBUG_ERROR, "status", | |
10006 | 625 "Cannot deactivate an exclusive status (%s).\n", |
626 gaim_status_type_get_id(status_type)); | |
9949 | 627 return; |
628 } | |
629 | |
630 presence = gaim_status_get_presence(status); | |
631 old_status = gaim_presence_get_active_status(presence); | |
632 | |
633 if (!gaim_status_type_is_independent(status_type)) | |
634 { | |
635 const GList *l; | |
636 | |
10006 | 637 for (l = gaim_presence_get_statuses(presence); l != NULL; l = l->next) |
9949 | 638 { |
10012 | 639 GaimStatusType *temp_type = l->data; |
640 GaimStatus *temp_status = NULL; | |
9949 | 641 |
10006 | 642 if (!gaim_status_compare(temp_status, status)) |
9949 | 643 continue; |
644 | |
645 if (gaim_status_type_is_independent(temp_type)) | |
646 continue; | |
647 | |
10012 | 648 |
649 temp_status = (GaimStatus *)g_hash_table_lookup( | |
650 presence->status_table, | |
651 gaim_status_type_get_id(temp_type)); | |
10013 | 652 |
9949 | 653 if (gaim_status_is_active(temp_status)) |
654 { | |
655 /* | |
656 * Since we don't want an infinite loop, we have to set | |
657 * the active variable ourself. | |
658 */ | |
659 temp_status->active = FALSE; | |
660 | |
661 notify_status_update(presence, old_status, temp_status); | |
662 | |
663 break; | |
664 } | |
665 } | |
666 } | |
667 | |
668 status->active = active; | |
6065 | 669 |
9949 | 670 notify_status_update(presence, old_status, status); |
671 } | |
672 | |
673 void | |
674 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
675 gboolean value) | |
676 { | |
677 GaimStatusType *status_type; | |
678 GaimStatusAttr *attr; | |
679 GaimValue *attr_value; | |
680 | |
681 g_return_if_fail(status != NULL); | |
682 g_return_if_fail(id != NULL); | |
683 | |
684 status_type = gaim_status_get_type(status); | |
685 | |
686 /* Make sure this attribute exists. */ | |
687 attr = gaim_status_type_get_attr(status_type, id); | |
688 g_return_if_fail(attr != NULL); | |
689 | |
690 attr_value = gaim_status_attr_get_value_type(attr); | |
691 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); | |
692 | |
693 gaim_value_set_boolean(attr_value, value); | |
694 } | |
695 | |
696 void | |
697 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
698 { | |
699 GaimStatusType *status_type; | |
700 GaimStatusAttr *attr; | |
701 GaimValue *attr_value; | |
702 | |
703 g_return_if_fail(status != NULL); | |
704 g_return_if_fail(id != NULL); | |
705 | |
706 status_type = gaim_status_get_type(status); | |
707 | |
708 /* Make sure this attribute exists. */ | |
709 attr = gaim_status_type_get_attr(status_type, id); | |
710 g_return_if_fail(attr != NULL); | |
711 | |
712 attr_value = gaim_status_attr_get_value_type(attr); | |
713 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); | |
714 | |
715 gaim_value_set_int(attr_value, value); | |
6065 | 716 } |
717 | |
9949 | 718 void |
719 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
720 const char *value) | |
721 { | |
722 GaimStatusType *status_type; | |
723 GaimStatusAttr *attr; | |
724 GaimValue *attr_value; | |
725 | |
726 g_return_if_fail(status != NULL); | |
727 g_return_if_fail(id != NULL); | |
728 | |
729 status_type = gaim_status_get_type(status); | |
730 | |
731 /* Make sure this attribute exists. */ | |
732 attr = gaim_status_type_get_attr(status_type, id); | |
733 g_return_if_fail(attr != NULL); | |
734 | |
735 attr_value = gaim_status_attr_get_value_type(attr); | |
736 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); | |
737 | |
738 gaim_value_set_string(attr_value, value); | |
739 } | |
740 | |
741 GaimStatusType * | |
742 gaim_status_get_type(const GaimStatus *status) | |
743 { | |
744 g_return_val_if_fail(status != NULL, NULL); | |
745 | |
746 return status->type; | |
747 } | |
748 | |
749 GaimPresence * | |
750 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 751 { |
9949 | 752 g_return_val_if_fail(status != NULL, NULL); |
753 | |
754 return status->presence; | |
755 } | |
756 | |
757 const char * | |
758 gaim_status_get_id(const GaimStatus *status) | |
759 { | |
760 g_return_val_if_fail(status != NULL, NULL); | |
761 | |
762 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
763 } | |
764 | |
765 const char * | |
766 gaim_status_get_name(const GaimStatus *status) | |
767 { | |
768 g_return_val_if_fail(status != NULL, NULL); | |
769 | |
770 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
771 } | |
772 | |
773 gboolean | |
774 gaim_status_is_independent(const GaimStatus *status) | |
775 { | |
776 g_return_val_if_fail(status != NULL, FALSE); | |
777 | |
778 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
779 } | |
780 | |
781 gboolean | |
782 gaim_status_is_available(const GaimStatus *status) | |
783 { | |
784 g_return_val_if_fail(status != NULL, FALSE); | |
785 | |
786 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
787 } | |
6216 | 788 |
9949 | 789 gboolean |
790 gaim_status_is_active(const GaimStatus *status) | |
791 { | |
792 g_return_val_if_fail(status != NULL, FALSE); | |
793 | |
794 return status->active; | |
795 } | |
796 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
797 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
798 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
799 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
800 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
801 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
802 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
803 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
804 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
805 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
806 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
807 primitive != GAIM_STATUS_OFFLINE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
808 } |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
809 |
9949 | 810 GaimValue * |
811 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
812 { | |
813 GaimStatusType *status_type; | |
814 GaimStatusAttr *attr; | |
815 | |
816 g_return_val_if_fail(status != NULL, NULL); | |
817 g_return_val_if_fail(id != NULL, NULL); | |
818 | |
819 status_type = gaim_status_get_type(status); | |
820 | |
821 /* Make sure this attribute exists. */ | |
822 attr = gaim_status_type_get_attr(status_type, id); | |
823 g_return_val_if_fail(attr != NULL, NULL); | |
824 | |
825 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
826 } | |
827 | |
828 gboolean | |
829 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
830 { | |
831 const GaimValue *value; | |
832 | |
833 g_return_val_if_fail(status != NULL, FALSE); | |
834 g_return_val_if_fail(id != NULL, FALSE); | |
835 | |
836 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
837 return FALSE; | |
838 | |
839 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, FALSE); | |
840 | |
841 return gaim_value_get_boolean(value); | |
842 } | |
843 | |
844 int | |
845 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
846 { | |
847 const GaimValue *value; | |
848 | |
849 g_return_val_if_fail(status != NULL, FALSE); | |
850 g_return_val_if_fail(id != NULL, FALSE); | |
851 | |
852 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
853 return FALSE; | |
854 | |
855 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
856 | |
857 return gaim_value_get_int(value); | |
858 } | |
859 | |
860 const char * | |
861 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
862 { | |
863 const GaimValue *value; | |
864 | |
865 g_return_val_if_fail(status != NULL, FALSE); | |
866 g_return_val_if_fail(id != NULL, FALSE); | |
867 | |
868 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
869 return FALSE; | |
870 | |
871 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
872 | |
873 return gaim_value_get_string(value); | |
874 } | |
875 | |
876 gint | |
877 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
878 { | |
879 GaimStatusType *type1, *type2; | |
880 int score1 = 0, score2 = 0; | |
6065 | 881 |
9949 | 882 if ((status1 == NULL && status2 == NULL) || |
883 (status1 == status2)) | |
884 { | |
885 return 0; | |
886 } | |
887 else if (status1 == NULL) | |
888 return 1; | |
889 else if (status2 == NULL) | |
890 return -1; | |
891 | |
892 type1 = gaim_status_get_type(status1); | |
893 type2 = gaim_status_get_type(status2); | |
894 | |
895 if (gaim_status_is_active(status1)) | |
896 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
897 | |
898 if (gaim_status_is_active(status2)) | |
899 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
900 | |
901 if (score1 > score2) | |
902 return -1; | |
903 else if (score1 < score2) | |
904 return 1; | |
905 | |
906 return 0; | |
907 } | |
908 | |
909 | |
910 /************************************************************************** | |
911 * GaimPresence API | |
912 **************************************************************************/ | |
913 GaimPresence * | |
914 gaim_presence_new(GaimPresenceContext context) | |
915 { | |
916 GaimPresence *presence; | |
917 | |
918 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
919 | |
920 presence = g_new0(GaimPresence, 1); | |
921 | |
922 presence->context = context; | |
923 | |
924 presence->status_table = | |
10009 | 925 g_hash_table_new_full(g_str_hash, g_str_equal, |
926 g_free, (GFreeFunc)gaim_status_destroy); | |
9949 | 927 |
928 return presence; | |
929 } | |
930 | |
931 GaimPresence * | |
932 gaim_presence_new_for_account(GaimAccount *account) | |
933 { | |
10012 | 934 GaimPresence *presence = NULL; |
9949 | 935 g_return_val_if_fail(account != NULL, NULL); |
936 | |
937 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
938 presence->u.account = account; | |
10006 | 939 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 940 |
941 return presence; | |
942 } | |
943 | |
944 GaimPresence * | |
945 gaim_presence_new_for_conv(GaimConversation *conv) | |
946 { | |
947 GaimPresence *presence; | |
948 | |
949 g_return_val_if_fail(conv != NULL, NULL); | |
950 | |
951 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
952 presence->u.chat.conv = conv; | |
10006 | 953 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 954 |
955 return presence; | |
956 } | |
6216 | 957 |
9949 | 958 GaimPresence * |
959 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
960 { | |
961 GaimPresence *presence; | |
962 GaimStatusBuddyKey *key; | |
10006 | 963 GaimAccount *account; |
9949 | 964 |
965 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 966 account = buddy->account; |
9949 | 967 |
10006 | 968 account = buddy->account; |
969 | |
9949 | 970 key = g_new0(GaimStatusBuddyKey, 1); |
971 key->account = buddy->account; | |
972 key->name = g_strdup(buddy->name); | |
10006 | 973 |
974 presence = g_hash_table_lookup(buddy_presences, key); | |
975 if (presence == NULL) | |
9949 | 976 { |
977 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
978 | |
979 presence->u.buddy.name = g_strdup(buddy->name); | |
980 presence->u.buddy.account = buddy->account; | |
10006 | 981 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 982 |
983 g_hash_table_insert(buddy_presences, key, presence); | |
984 } | |
985 else | |
986 { | |
987 g_free(key->name); | |
988 g_free(key); | |
989 } | |
990 | |
991 presence->u.buddy.ref_count++; | |
992 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
993 buddy); | |
994 | |
995 return presence; | |
996 } | |
997 | |
998 void | |
999 gaim_presence_destroy(GaimPresence *presence) | |
1000 { | |
1001 g_return_if_fail(presence != NULL); | |
6216 | 1002 |
9949 | 1003 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1004 { | |
1005 GaimStatusBuddyKey key; | |
1006 | |
1007 presence->u.buddy.ref_count--; | |
1008 | |
1009 g_return_if_fail(presence->u.buddy.ref_count == 0); | |
1010 | |
1011 key.account = presence->u.buddy.account; | |
1012 key.name = presence->u.buddy.name; | |
1013 | |
1014 g_hash_table_remove(buddy_presences, &key); | |
1015 | |
1016 if (presence->u.buddy.name != NULL) | |
1017 g_free(presence->u.buddy.name); | |
1018 } | |
1019 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1020 { | |
1021 if (presence->u.chat.user != NULL) | |
1022 g_free(presence->u.chat.user); | |
1023 } | |
1024 | |
10006 | 1025 if (buddy_presences != NULL) |
1026 g_hash_table_destroy(buddy_presences); | |
1027 | |
9949 | 1028 if (presence->statuses != NULL) |
1029 g_list_free(presence->statuses); | |
1030 | |
1031 g_hash_table_destroy(presence->status_table); | |
1032 | |
1033 g_free(presence); | |
1034 } | |
1035 | |
1036 void | |
1037 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
1038 { | |
1039 g_return_if_fail(presence != NULL); | |
1040 g_return_if_fail(buddy != NULL); | |
1041 g_return_if_fail(gaim_presence_get_context(presence) == | |
1042 GAIM_PRESENCE_CONTEXT_BUDDY); | |
1043 | |
1044 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
1045 { | |
1046 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
1047 buddy); | |
1048 presence->u.buddy.ref_count--; | |
1049 } | |
6065 | 1050 } |
1051 | |
9949 | 1052 void |
1053 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
1054 { | |
1055 g_return_if_fail(presence != NULL); | |
1056 g_return_if_fail(status != NULL); | |
1057 | |
1058 presence->statuses = g_list_append(presence->statuses, status); | |
1059 | |
1060 g_hash_table_insert(presence->status_table, | |
1061 g_strdup(gaim_status_get_id(status)), status); | |
1062 } | |
1063 | |
1064 void | |
1065 gaim_presence_add_presence(GaimPresence *presence, const GList *source_list) | |
1066 { | |
1067 const GList *l; | |
1068 | |
1069 g_return_if_fail(presence != NULL); | |
1070 g_return_if_fail(source_list != NULL); | |
1071 | |
1072 for (l = source_list; l != NULL; l = l->next) | |
1073 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
1074 } | |
1075 | |
1076 void | |
1077 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
1078 gboolean active) | |
1079 { | |
1080 GaimStatus *status; | |
1081 | |
1082 g_return_if_fail(presence != NULL); | |
1083 g_return_if_fail(status_id != NULL); | |
1084 | |
1085 status = gaim_presence_get_status(presence, status_id); | |
1086 | |
1087 g_return_if_fail(status != NULL); | |
1088 | |
1089 if (!gaim_status_is_independent(status)) | |
1090 { | |
1091 if (!active) | |
1092 { | |
1093 gaim_debug_warning("status", | |
1094 "Attempted to set a non-independent status " | |
1095 "(%s) inactive. Only independent statuses " | |
1096 "can be specifically marked inactive.", | |
1097 status_id); | |
1098 | |
1099 return; | |
1100 } | |
1101 | |
1102 if (presence->active_status != NULL) | |
1103 gaim_status_set_active(presence->active_status, FALSE); | |
1104 | |
1105 presence->active_status = status; | |
1106 } | |
1107 | |
1108 gaim_status_set_active(status, active); | |
1109 } | |
1110 | |
1111 void | |
1112 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
1113 { | |
1114 GaimStatus *status; | |
1115 | |
1116 g_return_if_fail(presence != NULL); | |
1117 g_return_if_fail(status_id != NULL); | |
1118 | |
1119 status = gaim_presence_get_status(presence, status_id); | |
1120 | |
1121 g_return_if_fail(status != NULL); | |
1122 | |
1123 if (gaim_status_is_independent(status)) | |
1124 return; | |
1125 | |
1126 if (presence->active_status != NULL) | |
1127 gaim_status_set_active(presence->active_status, FALSE); | |
1128 | |
1129 gaim_status_set_active(status, TRUE); | |
1130 } | |
1131 | |
1132 static void | |
1133 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
1134 time_t current_time, gboolean old_idle, gboolean idle) | |
1135 { | |
1136 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1137 | |
1138 if (!old_idle && idle) | |
1139 { | |
1140 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle", buddy); | |
1141 | |
1142 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1143 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1144 { | |
1145 GaimLog *log = gaim_account_get_log(buddy->account); | |
1146 char *tmp = g_strdup_printf(_("%s became idle"), | |
1147 gaim_buddy_get_alias(buddy)); | |
1148 | |
1149 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1150 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1151 g_free(tmp); | |
1152 } | |
1153 } | |
1154 else if (old_idle && !idle) | |
1155 { | |
1156 gaim_signal_emit(gaim_blist_get_handle(), "buddy-unidle", buddy); | |
1157 | |
1158 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1159 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1160 { | |
1161 GaimLog *log = gaim_account_get_log(buddy->account); | |
1162 char *tmp = g_strdup_printf(_("%s became unidle"), | |
1163 gaim_buddy_get_alias(buddy)); | |
1164 | |
1165 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1166 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1167 g_free(tmp); | |
1168 } | |
1169 } | |
1170 | |
1171 gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); | |
1172 | |
1173 if (ops != NULL && ops->update != NULL) | |
1174 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
1175 } | |
1176 | |
1177 void | |
1178 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
1179 { | |
1180 gboolean old_idle; | |
1181 | |
1182 g_return_if_fail(presence != NULL); | |
1183 | |
1184 if (presence->idle == idle && presence->idle_time == idle_time) | |
1185 return; | |
1186 | |
1187 old_idle = presence->idle; | |
1188 presence->idle = idle; | |
1189 presence->idle_time = (idle ? idle_time : 0); | |
1190 | |
1191 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1192 { | |
1193 const GList *l; | |
1194 time_t current_time = time(NULL); | |
1195 | |
1196 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
1197 { | |
1198 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
1199 old_idle, idle); | |
1200 } | |
1201 } | |
1202 } | |
1203 | |
1204 void | |
10006 | 1205 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
1206 { | |
1207 g_return_if_fail(presence != NULL); | |
1208 | |
1209 if (presence->login_time == login_time) | |
1210 return; | |
1211 | |
1212 presence->login_time = login_time; | |
1213 } | |
1214 | |
1215 void | |
9949 | 1216 gaim_presence_set_warning_level(GaimPresence *presence, unsigned int level) |
6065 | 1217 { |
9949 | 1218 g_return_if_fail(presence != NULL); |
1219 g_return_if_fail(level <= 100); | |
1220 | |
1221 if (presence->warning_level == level) | |
1222 return; | |
1223 | |
1224 presence->warning_level = level; | |
1225 | |
1226 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1227 { | |
1228 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1229 | |
1230 if (ops != NULL && ops->update != NULL) | |
1231 { | |
1232 const GList *l; | |
1233 | |
1234 for (l = gaim_presence_get_buddies(presence); | |
1235 l != NULL; | |
1236 l = l->next) | |
1237 { | |
1238 ops->update(gaim_get_blist(), (GaimBlistNode *)l->data); | |
1239 } | |
1240 } | |
1241 } | |
1242 } | |
1243 | |
1244 GaimPresenceContext | |
1245 gaim_presence_get_context(const GaimPresence *presence) | |
1246 { | |
1247 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
1248 | |
1249 return presence->context; | |
1250 } | |
1251 | |
1252 GaimAccount * | |
1253 gaim_presence_get_account(const GaimPresence *presence) | |
1254 { | |
1255 GaimPresenceContext context; | |
1256 | |
1257 g_return_val_if_fail(presence != NULL, NULL); | |
1258 | |
1259 context = gaim_presence_get_context(presence); | |
1260 | |
1261 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
1262 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1263 | |
1264 return presence->u.account; | |
1265 } | |
1266 | |
1267 GaimConversation * | |
1268 gaim_presence_get_conversation(const GaimPresence *presence) | |
1269 { | |
1270 g_return_val_if_fail(presence != NULL, NULL); | |
1271 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1272 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1273 | |
1274 return presence->u.chat.conv; | |
1275 } | |
1276 | |
1277 const char * | |
1278 gaim_presence_get_chat_user(const GaimPresence *presence) | |
1279 { | |
1280 g_return_val_if_fail(presence != NULL, NULL); | |
1281 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1282 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1283 | |
1284 return presence->u.chat.user; | |
1285 } | |
1286 | |
1287 const GList * | |
1288 gaim_presence_get_buddies(const GaimPresence *presence) | |
1289 { | |
1290 g_return_val_if_fail(presence != NULL, NULL); | |
1291 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1292 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1293 | |
1294 return presence->u.buddy.buddies; | |
1295 } | |
1296 | |
1297 const GList * | |
1298 gaim_presence_get_statuses(const GaimPresence *presence) | |
1299 { | |
1300 g_return_val_if_fail(presence != NULL, NULL); | |
1301 | |
1302 return presence->statuses; | |
1303 } | |
1304 | |
1305 GaimStatus * | |
1306 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
1307 { | |
1308 GaimStatus *status; | |
10006 | 1309 const GList *l = NULL; |
9949 | 1310 |
1311 g_return_val_if_fail(presence != NULL, NULL); | |
1312 g_return_val_if_fail(status_id != NULL, NULL); | |
1313 | |
10006 | 1314 /* What's the purpose of this hash table? */ |
10012 | 1315 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
10006 | 1316 status_id); |
10012 | 1317 |
10006 | 1318 if (status == NULL) { |
10012 | 1319 for (l = gaim_presence_get_statuses(presence); |
10006 | 1320 l != NULL && status == NULL; l = l->next) |
1321 { | |
1322 GaimStatus *temp_status = l->data; | |
10012 | 1323 |
10006 | 1324 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
1325 status = temp_status; | |
1326 } | |
1327 | |
1328 if (status != NULL) | |
1329 g_hash_table_insert(presence->status_table, | |
1330 g_strdup(gaim_status_get_id(status)), status); | |
10012 | 1331 } |
9949 | 1332 |
1333 return status; | |
1334 } | |
1335 | |
1336 GaimStatus * | |
1337 gaim_presence_get_active_status(const GaimPresence *presence) | |
1338 { | |
1339 g_return_val_if_fail(presence != NULL, NULL); | |
1340 | |
1341 return presence->active_status; | |
1342 } | |
1343 | |
1344 gboolean | |
1345 gaim_presence_is_available(const GaimPresence *presence) | |
1346 { | |
1347 GaimStatus *status; | |
1348 | |
1349 g_return_val_if_fail(presence != NULL, FALSE); | |
1350 | |
1351 status = gaim_presence_get_active_status(presence); | |
1352 | |
1353 return ((status != NULL && gaim_status_is_available(status)) && | |
1354 !gaim_presence_is_idle(presence)); | |
1355 } | |
1356 | |
1357 gboolean | |
1358 gaim_presence_is_online(const GaimPresence *presence) | |
1359 { | |
1360 GaimStatus *status; | |
1361 | |
1362 g_return_val_if_fail(presence != NULL, FALSE); | |
1363 | |
1364 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
1365 return FALSE; | |
1366 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1367 return gaim_status_is_online(status); |
9949 | 1368 } |
1369 | |
1370 gboolean | |
1371 gaim_presence_is_status_active(const GaimPresence *presence, | |
1372 const char *status_id) | |
1373 { | |
1374 GaimStatus *status; | |
1375 | |
1376 g_return_val_if_fail(presence != NULL, FALSE); | |
1377 g_return_val_if_fail(status_id != NULL, FALSE); | |
1378 | |
1379 status = gaim_presence_get_status(presence, status_id); | |
1380 | |
1381 return (status != NULL && gaim_status_is_active(status)); | |
1382 } | |
1383 | |
1384 gboolean | |
1385 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
1386 GaimStatusPrimitive primitive) | |
1387 { | |
1388 GaimStatus *status; | |
1389 GaimStatusType *status_type; | |
1390 | |
1391 g_return_val_if_fail(presence != NULL, FALSE); | |
1392 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
1393 | |
1394 status = gaim_presence_get_active_status(presence); | |
1395 status_type = gaim_status_get_type(status); | |
1396 | |
1397 if (gaim_status_type_get_primitive(status_type) == primitive) | |
1398 return TRUE; | |
6065 | 1399 |
1400 return FALSE; | |
1401 } | |
1402 | |
9949 | 1403 gboolean |
1404 gaim_presence_is_idle(const GaimPresence *presence) | |
6065 | 1405 { |
9949 | 1406 g_return_val_if_fail(presence != NULL, FALSE); |
1407 | |
1408 return presence->idle; | |
6065 | 1409 } |
1410 | |
9949 | 1411 time_t |
1412 gaim_presence_get_idle_time(const GaimPresence *presence) | |
6065 | 1413 { |
9949 | 1414 g_return_val_if_fail(presence != NULL, 0); |
6065 | 1415 |
9949 | 1416 return presence->idle_time; |
1417 } | |
6065 | 1418 |
9949 | 1419 unsigned int |
1420 gaim_presence_get_warning_level(const GaimPresence *presence) | |
1421 { | |
1422 g_return_val_if_fail(presence != NULL, 0); | |
6216 | 1423 |
9949 | 1424 return presence->warning_level; |
6065 | 1425 } |
1426 | |
9949 | 1427 gint |
1428 gaim_presence_compare(const GaimPresence *presence1, | |
1429 const GaimPresence *presence2) | |
6065 | 1430 { |
9949 | 1431 gboolean idle1, idle2; |
1432 size_t idle_time_1, idle_time_2; | |
1433 int score1 = 0, score2 = 0; | |
1434 const GList *l; | |
6065 | 1435 |
9949 | 1436 if ((presence1 == NULL && presence2 == NULL) || (presence1 == presence2)) |
1437 return 0; | |
1438 else if (presence1 == NULL) | |
1439 return -1; | |
1440 else if (presence2 == NULL) | |
1441 return 1; | |
6065 | 1442 |
9949 | 1443 /* Compute the score of the first set of statuses. */ |
1444 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1445 { | |
1446 GaimStatus *status = (GaimStatus *)l->data; | |
1447 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1448 |
9949 | 1449 if (gaim_status_is_active(status)) |
1450 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1451 } |
1452 | |
9949 | 1453 /* Compute the score of the second set of statuses. */ |
1454 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1455 { | |
1456 GaimStatus *status = (GaimStatus *)l->data; | |
1457 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1458 |
9949 | 1459 if (gaim_status_is_active(status)) |
1460 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1461 } |
1462 | |
9949 | 1463 idle1 = gaim_presence_is_idle(presence1); |
1464 idle2 = gaim_presence_is_idle(presence2); | |
6065 | 1465 |
9949 | 1466 if (idle1) |
1467 score1 += primitive_scores[SCORE_IDLE]; | |
6065 | 1468 |
9949 | 1469 if (idle2) |
1470 score2 += primitive_scores[SCORE_IDLE]; | |
6065 | 1471 |
9949 | 1472 idle_time_1 = gaim_presence_get_idle_time(presence1); |
1473 idle_time_2 = gaim_presence_get_idle_time(presence2); | |
6065 | 1474 |
9949 | 1475 if (idle_time_1 > idle_time_2) |
1476 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
1477 else if (idle_time_1 < idle_time_2) | |
1478 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
6065 | 1479 |
9949 | 1480 if (score1 < score2) |
1481 return 1; | |
1482 else if (score1 > score2) | |
1483 return -1; | |
1484 | |
1485 return 0; | |
1486 } | |
1487 | |
6065 | 1488 |
9949 | 1489 /************************************************************************** |
1490 * Status subsystem | |
1491 **************************************************************************/ | |
1492 static void | |
1493 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
1494 gpointer data) | |
1495 { | |
1496 int index = GPOINTER_TO_INT(data); | |
6065 | 1497 |
9949 | 1498 primitive_scores[index] = GPOINTER_TO_INT(value); |
6065 | 1499 } |
1500 | |
10012 | 1501 guint |
10006 | 1502 gaim_buddy_presences_hash(gconstpointer key) |
1503 { | |
10012 | 1504 const GaimStatusBuddyKey *me = key; |
1505 guint ret; | |
1506 char *str; | |
1507 | |
1508 str = g_strdup_printf("%p%s", me->account, me->name); | |
1509 ret = g_str_hash(str); | |
1510 g_free(str); | |
1511 | |
1512 return ret; | |
10006 | 1513 } |
1514 | |
10012 | 1515 gboolean |
10006 | 1516 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
1517 { | |
1518 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
1519 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
1520 | |
10012 | 1521 if(key_a->account == key_b->account && |
1522 !strcmp(key_a->name, key_b->name)) | |
10006 | 1523 return TRUE; |
1524 else | |
1525 return FALSE; | |
1526 } | |
1527 | |
9949 | 1528 void |
1529 gaim_statuses_init(void) | |
6065 | 1530 { |
9949 | 1531 gaim_prefs_add_none("/core/status"); |
1532 gaim_prefs_add_none("/core/status/scores"); | |
6065 | 1533 |
9949 | 1534 gaim_prefs_add_int("/core/status/scores/offline", |
1535 primitive_scores[GAIM_STATUS_OFFLINE]); | |
1536 gaim_prefs_add_int("/core/status/scores/available", | |
1537 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
1538 gaim_prefs_add_int("/core/status/scores/hidden", | |
1539 primitive_scores[GAIM_STATUS_HIDDEN]); | |
1540 gaim_prefs_add_int("/core/status/scores/away", | |
1541 primitive_scores[GAIM_STATUS_AWAY]); | |
1542 gaim_prefs_add_int("/core/status/scores/extended_away", | |
1543 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
1544 gaim_prefs_add_int("/core/status/scores/idle", | |
1545 primitive_scores[SCORE_IDLE]); | |
6065 | 1546 |
9949 | 1547 gaim_prefs_connect_callback("/core/status/scores/offline", |
1548 score_pref_changed_cb, | |
1549 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
1550 gaim_prefs_connect_callback("/core/status/scores/available", | |
1551 score_pref_changed_cb, | |
1552 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
1553 gaim_prefs_connect_callback("/core/status/scores/hidden", | |
1554 score_pref_changed_cb, | |
1555 GINT_TO_POINTER(GAIM_STATUS_HIDDEN)); | |
1556 gaim_prefs_connect_callback("/core/status/scores/away", | |
1557 score_pref_changed_cb, | |
1558 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
1559 gaim_prefs_connect_callback("/core/status/scores/extended_away", | |
1560 score_pref_changed_cb, | |
1561 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
1562 gaim_prefs_connect_callback("/core/status/scores/idle", | |
1563 score_pref_changed_cb, | |
1564 GINT_TO_POINTER(SCORE_IDLE)); | |
10006 | 1565 |
1566 buddy_presences = g_hash_table_new(gaim_buddy_presences_hash, | |
1567 gaim_buddy_presences_equal); | |
9949 | 1568 } |
6065 | 1569 |
9949 | 1570 void |
1571 gaim_statuses_uninit(void) | |
1572 { | |
1573 } | |
6065 | 1574 |
9949 | 1575 void |
1576 gaim_statuses_sync(void) | |
1577 { | |
6065 | 1578 } |
9949 | 1579 |
1580 void | |
1581 gaim_statuses_load(void) | |
1582 { | |
1583 } |