Mercurial > pidgin
annotate src/status.c @ 10138:5fb5c447eb4f
[gaim-migrate @ 11208]
Bring back the old smiley selection dialog for gtk<2.4 and play around
with the signals for both of them. We're not explicitly freeing the
smiley menu in gtk2.4 anymore... can someone verify that gtk is
freeing it for us? Or write a patch to free it, if not? This would
probably be a pretty big memleak if gtk isn't taking care of it...
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Mon, 25 Oct 2004 02:48:38 +0000 |
parents | 9fdbfe832fac |
children | d83e6f2125b1 |
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" |
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 | |
10067 | 375 gaim_status_type_is_exclusive(const GaimStatusType *status_type) |
376 { | |
377 g_return_val_if_fail(status_type != NULL, FALSE); | |
378 | |
379 return !status_type->independent; | |
380 } | |
381 | |
382 gboolean | |
9949 | 383 gaim_status_type_is_available(const GaimStatusType *status_type) |
384 { | |
385 GaimStatusPrimitive primitive; | |
386 | |
387 g_return_val_if_fail(status_type != NULL, FALSE); | |
388 | |
389 primitive = gaim_status_type_get_primitive(status_type); | |
390 | |
391 return (primitive == GAIM_STATUS_AVAILABLE || | |
392 primitive == GAIM_STATUS_HIDDEN); | |
393 } | |
394 | |
395 const char * | |
396 gaim_status_type_get_primary_attr(const GaimStatusType *status_type) | |
397 { | |
398 g_return_val_if_fail(status_type != NULL, NULL); | |
399 | |
400 return status_type->primary_attr_id; | |
401 } | |
402 | |
403 GaimStatusAttr * | |
404 gaim_status_type_get_attr(const GaimStatusType *status_type, const char *id) | |
405 { | |
406 GList *l; | |
407 | |
408 g_return_val_if_fail(status_type != NULL, NULL); | |
409 g_return_val_if_fail(id != NULL, NULL); | |
410 | |
411 for (l = status_type->attrs; l != NULL; l = l->next) | |
412 { | |
413 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
414 | |
415 if (!strcmp(gaim_status_attr_get_id(attr), id)) | |
416 return attr; | |
417 } | |
418 | |
419 return NULL; | |
420 } | |
421 | |
422 const GList * | |
423 gaim_status_type_get_attrs(const GaimStatusType *status_type) | |
424 { | |
425 g_return_val_if_fail(status_type != NULL, NULL); | |
426 | |
427 return status_type->attrs; | |
428 } | |
429 | |
430 | |
431 /************************************************************************** | |
432 * GaimStatusAttr API | |
433 **************************************************************************/ | |
434 GaimStatusAttr * | |
435 gaim_status_attr_new(const char *id, const char *name, GaimValue *value_type) | |
436 { | |
437 GaimStatusAttr *attr; | |
438 | |
439 g_return_val_if_fail(id != NULL, NULL); | |
440 g_return_val_if_fail(name != NULL, NULL); | |
441 g_return_val_if_fail(value_type != NULL, NULL); | |
442 | |
443 attr = g_new0(GaimStatusAttr, 1); | |
444 | |
445 attr->id = g_strdup(id); | |
446 attr->name = g_strdup(name); | |
447 attr->value_type = value_type; | |
448 | |
449 return attr; | |
450 } | |
451 | |
452 void | |
453 gaim_status_attr_destroy(GaimStatusAttr *attr) | |
454 { | |
455 g_return_if_fail(attr != NULL); | |
456 | |
457 g_free(attr->id); | |
458 g_free(attr->name); | |
459 | |
460 gaim_value_destroy(attr->value_type); | |
461 | |
462 g_free(attr); | |
463 } | |
464 | |
465 const char * | |
466 gaim_status_attr_get_id(const GaimStatusAttr *attr) | |
467 { | |
468 g_return_val_if_fail(attr != NULL, NULL); | |
469 | |
470 return attr->id; | |
471 } | |
472 | |
473 const char * | |
474 gaim_status_attr_get_name(const GaimStatusAttr *attr) | |
475 { | |
476 g_return_val_if_fail(attr != NULL, NULL); | |
477 | |
478 return attr->name; | |
479 } | |
480 | |
481 GaimValue * | |
482 gaim_status_attr_get_value_type(const GaimStatusAttr *attr) | |
483 { | |
484 g_return_val_if_fail(attr != NULL, NULL); | |
485 | |
486 return attr->value_type; | |
487 } | |
488 | |
489 | |
490 /************************************************************************** | |
491 * GaimStatus API | |
492 **************************************************************************/ | |
493 GaimStatus * | |
494 gaim_status_new(GaimStatusType *status_type, GaimPresence *presence) | |
495 { | |
496 GaimStatus *status; | |
497 const GList *l; | |
498 | |
499 g_return_val_if_fail(status_type != NULL, NULL); | |
500 g_return_val_if_fail(presence != NULL, NULL); | |
501 | |
502 status = g_new0(GaimStatus, 1); | |
503 | |
504 status->type = status_type; | |
505 status->presence = presence; | |
506 | |
507 status->attr_values = | |
508 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
509 (GDestroyNotify)gaim_value_destroy); | |
510 | |
511 for (l = gaim_status_type_get_attrs(status_type); l != NULL; l = l->next) | |
512 { | |
513 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
514 GaimValue *value = gaim_status_attr_get_value_type(attr); | |
515 GaimValue *new_value = gaim_value_dup(value); | |
516 | |
517 g_hash_table_insert(status->attr_values, | |
518 g_strdup(gaim_status_attr_get_id(attr)), new_value); | |
519 } | |
520 | |
521 return status; | |
522 } | |
523 | |
524 void | |
525 gaim_status_destroy(GaimStatus *status) | |
526 { | |
527 g_return_if_fail(status != NULL); | |
528 | |
529 gaim_status_set_active(status, FALSE); | |
530 | |
531 g_hash_table_destroy(status->attr_values); | |
532 | |
533 g_free(status); | |
534 } | |
6065 | 535 |
536 static void | |
9949 | 537 notify_buddy_status_update(GaimBuddy *buddy, GaimPresence *presence, |
538 GaimStatus *old_status, GaimStatus *new_status) | |
539 { | |
540 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | |
541 | |
542 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
543 gaim_prefs_get_bool("/core/logging/log_away_state")) | |
544 { | |
545 time_t current_time = time(NULL); | |
546 const char *buddy_alias = gaim_buddy_get_alias(buddy); | |
547 char *tmp = NULL; | |
548 | |
549 if (!gaim_status_is_available(old_status) && | |
550 gaim_status_is_available(new_status)) | |
551 { | |
552 tmp = g_strdup_printf(_("%s came back"), buddy_alias); | |
553 } | |
554 else if (gaim_status_is_available(old_status) && | |
555 !gaim_status_is_available(new_status)) | |
556 { | |
557 tmp = g_strdup_printf(_("%s went away"), buddy_alias); | |
558 } | |
559 | |
560 if (tmp != NULL) | |
561 { | |
562 GaimLog *log = gaim_account_get_log(buddy->account); | |
563 | |
564 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, | |
565 current_time, tmp); | |
566 g_free(tmp); | |
567 } | |
568 } | |
569 | |
10012 | 570 |
571 | |
572 if (ops != NULL && ops->update != NULL) | |
573 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 574 } |
575 | |
576 static void | |
577 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
578 GaimStatus *new_status) | |
6065 | 579 { |
9949 | 580 GaimPresenceContext context = gaim_presence_get_context(presence); |
581 | |
10006 | 582 gaim_debug_info("notify_status_update", "Context is %d\n", context); |
583 | |
9949 | 584 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) |
585 { | |
586 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); | |
587 | |
588 if (ops != NULL && ops->status_changed != NULL) | |
589 { | |
590 ops->status_changed(gaim_presence_get_account(presence), | |
591 new_status); | |
592 } | |
593 } | |
594 else if (context == GAIM_PRESENCE_CONTEXT_CONV) | |
595 { | |
596 /* TODO */ | |
597 #if 0 | |
598 GaimConversationUiOps *ops; | |
599 GaimConversation *conv; | |
600 | |
601 conv = gaim_status_get_conversation(new_status); | |
602 #endif | |
603 } | |
604 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
605 { | |
606 const GList *l; | |
607 | |
608 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
609 { | |
610 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
611 old_status, new_status); | |
612 } | |
613 } | |
614 } | |
615 | |
616 void | |
617 gaim_status_set_active(GaimStatus *status, gboolean active) | |
618 { | |
619 GaimStatusType *status_type; | |
620 GaimPresence *presence; | |
621 GaimStatus *old_status; | |
622 | |
623 g_return_if_fail(status != NULL); | |
624 | |
625 if (status->active == active) | |
626 return; | |
627 | |
628 status_type = gaim_status_get_type(status); | |
6065 | 629 |
10067 | 630 if (!active && gaim_status_type_is_exclusive(status_type)) |
9949 | 631 { |
10052 | 632 gaim_debug_error("status", |
10006 | 633 "Cannot deactivate an exclusive status (%s).\n", |
634 gaim_status_type_get_id(status_type)); | |
9949 | 635 return; |
636 } | |
637 | |
638 presence = gaim_status_get_presence(status); | |
639 old_status = gaim_presence_get_active_status(presence); | |
640 | |
10067 | 641 if (gaim_status_type_is_exclusive(status_type)) |
9949 | 642 { |
643 const GList *l; | |
644 | |
10006 | 645 for (l = gaim_presence_get_statuses(presence); l != NULL; l = l->next) |
9949 | 646 { |
10056
b566449d45f8
[gaim-migrate @ 11021]
Luke Schierer <lschiere@pidgin.im>
parents:
10052
diff
changeset
|
647 GaimStatus *temp_status = l->data; |
b566449d45f8
[gaim-migrate @ 11021]
Luke Schierer <lschiere@pidgin.im>
parents:
10052
diff
changeset
|
648 GaimStatusType *temp_type; |
9949 | 649 |
10056
b566449d45f8
[gaim-migrate @ 11021]
Luke Schierer <lschiere@pidgin.im>
parents:
10052
diff
changeset
|
650 temp_type = gaim_status_get_type(temp_status); |
9949 | 651 |
652 if (gaim_status_type_is_independent(temp_type)) | |
653 continue; | |
654 | |
655 if (gaim_status_is_active(temp_status)) | |
656 { | |
657 /* | |
658 * Since we don't want an infinite loop, we have to set | |
659 * the active variable ourself. | |
660 */ | |
661 temp_status->active = FALSE; | |
662 | |
663 notify_status_update(presence, old_status, temp_status); | |
664 | |
665 break; | |
666 } | |
667 } | |
668 } | |
669 | |
670 status->active = active; | |
6065 | 671 |
9949 | 672 notify_status_update(presence, old_status, status); |
673 } | |
674 | |
675 void | |
676 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
677 gboolean value) | |
678 { | |
679 GaimStatusType *status_type; | |
680 GaimStatusAttr *attr; | |
681 GaimValue *attr_value; | |
682 | |
683 g_return_if_fail(status != NULL); | |
684 g_return_if_fail(id != NULL); | |
685 | |
686 status_type = gaim_status_get_type(status); | |
687 | |
688 /* Make sure this attribute exists. */ | |
689 attr = gaim_status_type_get_attr(status_type, id); | |
690 g_return_if_fail(attr != NULL); | |
691 | |
692 attr_value = gaim_status_attr_get_value_type(attr); | |
693 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); | |
694 | |
695 gaim_value_set_boolean(attr_value, value); | |
696 } | |
697 | |
698 void | |
699 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
700 { | |
701 GaimStatusType *status_type; | |
702 GaimStatusAttr *attr; | |
703 GaimValue *attr_value; | |
704 | |
705 g_return_if_fail(status != NULL); | |
706 g_return_if_fail(id != NULL); | |
707 | |
708 status_type = gaim_status_get_type(status); | |
709 | |
710 /* Make sure this attribute exists. */ | |
711 attr = gaim_status_type_get_attr(status_type, id); | |
712 g_return_if_fail(attr != NULL); | |
713 | |
714 attr_value = gaim_status_attr_get_value_type(attr); | |
715 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); | |
716 | |
717 gaim_value_set_int(attr_value, value); | |
6065 | 718 } |
719 | |
9949 | 720 void |
721 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
722 const char *value) | |
723 { | |
724 GaimStatusType *status_type; | |
725 GaimStatusAttr *attr; | |
726 GaimValue *attr_value; | |
727 | |
728 g_return_if_fail(status != NULL); | |
729 g_return_if_fail(id != NULL); | |
730 | |
731 status_type = gaim_status_get_type(status); | |
732 | |
733 /* Make sure this attribute exists. */ | |
734 attr = gaim_status_type_get_attr(status_type, id); | |
735 g_return_if_fail(attr != NULL); | |
736 | |
737 attr_value = gaim_status_attr_get_value_type(attr); | |
738 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); | |
739 | |
740 gaim_value_set_string(attr_value, value); | |
741 } | |
742 | |
743 GaimStatusType * | |
744 gaim_status_get_type(const GaimStatus *status) | |
745 { | |
746 g_return_val_if_fail(status != NULL, NULL); | |
747 | |
748 return status->type; | |
749 } | |
750 | |
751 GaimPresence * | |
752 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 753 { |
9949 | 754 g_return_val_if_fail(status != NULL, NULL); |
755 | |
756 return status->presence; | |
757 } | |
758 | |
759 const char * | |
760 gaim_status_get_id(const GaimStatus *status) | |
761 { | |
762 g_return_val_if_fail(status != NULL, NULL); | |
763 | |
764 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
765 } | |
766 | |
767 const char * | |
768 gaim_status_get_name(const GaimStatus *status) | |
769 { | |
770 g_return_val_if_fail(status != NULL, NULL); | |
771 | |
772 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
773 } | |
774 | |
775 gboolean | |
776 gaim_status_is_independent(const GaimStatus *status) | |
777 { | |
778 g_return_val_if_fail(status != NULL, FALSE); | |
779 | |
780 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
781 } | |
782 | |
783 gboolean | |
10067 | 784 gaim_status_is_exclusive(const GaimStatus *status) |
785 { | |
786 g_return_val_if_fail(status != NULL, FALSE); | |
787 | |
788 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
789 } | |
790 | |
791 gboolean | |
9949 | 792 gaim_status_is_available(const GaimStatus *status) |
793 { | |
794 g_return_val_if_fail(status != NULL, FALSE); | |
795 | |
796 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
797 } | |
6216 | 798 |
9949 | 799 gboolean |
800 gaim_status_is_active(const GaimStatus *status) | |
801 { | |
802 g_return_val_if_fail(status != NULL, FALSE); | |
803 | |
804 return status->active; | |
805 } | |
806 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
807 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
808 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
809 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
810 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
811 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
812 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
813 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
814 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
815 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
816 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
817 primitive != GAIM_STATUS_OFFLINE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
818 } |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
819 |
9949 | 820 GaimValue * |
821 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
822 { | |
823 GaimStatusType *status_type; | |
824 GaimStatusAttr *attr; | |
825 | |
826 g_return_val_if_fail(status != NULL, NULL); | |
827 g_return_val_if_fail(id != NULL, NULL); | |
828 | |
829 status_type = gaim_status_get_type(status); | |
830 | |
831 /* Make sure this attribute exists. */ | |
832 attr = gaim_status_type_get_attr(status_type, id); | |
833 g_return_val_if_fail(attr != NULL, NULL); | |
834 | |
835 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
836 } | |
837 | |
838 gboolean | |
839 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
840 { | |
841 const GaimValue *value; | |
842 | |
843 g_return_val_if_fail(status != NULL, FALSE); | |
844 g_return_val_if_fail(id != NULL, FALSE); | |
845 | |
846 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
847 return FALSE; | |
848 | |
849 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, FALSE); | |
850 | |
851 return gaim_value_get_boolean(value); | |
852 } | |
853 | |
854 int | |
855 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
856 { | |
857 const GaimValue *value; | |
858 | |
859 g_return_val_if_fail(status != NULL, FALSE); | |
860 g_return_val_if_fail(id != NULL, FALSE); | |
861 | |
862 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
863 return FALSE; | |
864 | |
865 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
866 | |
867 return gaim_value_get_int(value); | |
868 } | |
869 | |
870 const char * | |
871 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
872 { | |
873 const GaimValue *value; | |
874 | |
875 g_return_val_if_fail(status != NULL, FALSE); | |
876 g_return_val_if_fail(id != NULL, FALSE); | |
877 | |
878 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
879 return FALSE; | |
880 | |
881 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
882 | |
883 return gaim_value_get_string(value); | |
884 } | |
885 | |
886 gint | |
887 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
888 { | |
889 GaimStatusType *type1, *type2; | |
890 int score1 = 0, score2 = 0; | |
6065 | 891 |
9949 | 892 if ((status1 == NULL && status2 == NULL) || |
893 (status1 == status2)) | |
894 { | |
895 return 0; | |
896 } | |
897 else if (status1 == NULL) | |
898 return 1; | |
899 else if (status2 == NULL) | |
900 return -1; | |
901 | |
902 type1 = gaim_status_get_type(status1); | |
903 type2 = gaim_status_get_type(status2); | |
904 | |
905 if (gaim_status_is_active(status1)) | |
906 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
907 | |
908 if (gaim_status_is_active(status2)) | |
909 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
910 | |
911 if (score1 > score2) | |
912 return -1; | |
913 else if (score1 < score2) | |
914 return 1; | |
915 | |
916 return 0; | |
917 } | |
918 | |
919 | |
920 /************************************************************************** | |
921 * GaimPresence API | |
922 **************************************************************************/ | |
923 GaimPresence * | |
924 gaim_presence_new(GaimPresenceContext context) | |
925 { | |
926 GaimPresence *presence; | |
927 | |
928 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
929 | |
930 presence = g_new0(GaimPresence, 1); | |
931 | |
932 presence->context = context; | |
933 | |
934 presence->status_table = | |
10009 | 935 g_hash_table_new_full(g_str_hash, g_str_equal, |
936 g_free, (GFreeFunc)gaim_status_destroy); | |
9949 | 937 |
938 return presence; | |
939 } | |
940 | |
941 GaimPresence * | |
942 gaim_presence_new_for_account(GaimAccount *account) | |
943 { | |
10012 | 944 GaimPresence *presence = NULL; |
9949 | 945 g_return_val_if_fail(account != NULL, NULL); |
946 | |
947 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
948 presence->u.account = account; | |
10006 | 949 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 950 |
951 return presence; | |
952 } | |
953 | |
954 GaimPresence * | |
955 gaim_presence_new_for_conv(GaimConversation *conv) | |
956 { | |
957 GaimPresence *presence; | |
958 | |
959 g_return_val_if_fail(conv != NULL, NULL); | |
960 | |
961 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
962 presence->u.chat.conv = conv; | |
10006 | 963 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 964 |
965 return presence; | |
966 } | |
6216 | 967 |
9949 | 968 GaimPresence * |
969 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
970 { | |
971 GaimPresence *presence; | |
972 GaimStatusBuddyKey *key; | |
10006 | 973 GaimAccount *account; |
9949 | 974 |
975 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 976 account = buddy->account; |
9949 | 977 |
10006 | 978 account = buddy->account; |
979 | |
9949 | 980 key = g_new0(GaimStatusBuddyKey, 1); |
981 key->account = buddy->account; | |
982 key->name = g_strdup(buddy->name); | |
10006 | 983 |
984 presence = g_hash_table_lookup(buddy_presences, key); | |
985 if (presence == NULL) | |
9949 | 986 { |
987 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
988 | |
989 presence->u.buddy.name = g_strdup(buddy->name); | |
990 presence->u.buddy.account = buddy->account; | |
10006 | 991 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 992 |
993 g_hash_table_insert(buddy_presences, key, presence); | |
994 } | |
995 else | |
996 { | |
997 g_free(key->name); | |
998 g_free(key); | |
999 } | |
1000 | |
1001 presence->u.buddy.ref_count++; | |
1002 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
1003 buddy); | |
1004 | |
1005 return presence; | |
1006 } | |
1007 | |
1008 void | |
1009 gaim_presence_destroy(GaimPresence *presence) | |
1010 { | |
1011 g_return_if_fail(presence != NULL); | |
6216 | 1012 |
9949 | 1013 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1014 { | |
1015 GaimStatusBuddyKey key; | |
1016 | |
1017 presence->u.buddy.ref_count--; | |
1018 | |
10077 | 1019 if(presence->u.buddy.ref_count != 0) |
1020 return; | |
9949 | 1021 |
1022 key.account = presence->u.buddy.account; | |
1023 key.name = presence->u.buddy.name; | |
1024 | |
1025 g_hash_table_remove(buddy_presences, &key); | |
1026 | |
1027 if (presence->u.buddy.name != NULL) | |
1028 g_free(presence->u.buddy.name); | |
1029 } | |
1030 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1031 { | |
1032 if (presence->u.chat.user != NULL) | |
1033 g_free(presence->u.chat.user); | |
1034 } | |
1035 | |
1036 if (presence->statuses != NULL) | |
1037 g_list_free(presence->statuses); | |
1038 | |
1039 g_hash_table_destroy(presence->status_table); | |
1040 | |
1041 g_free(presence); | |
1042 } | |
1043 | |
1044 void | |
1045 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
1046 { | |
1047 g_return_if_fail(presence != NULL); | |
1048 g_return_if_fail(buddy != NULL); | |
1049 g_return_if_fail(gaim_presence_get_context(presence) == | |
1050 GAIM_PRESENCE_CONTEXT_BUDDY); | |
1051 | |
1052 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
1053 { | |
1054 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
1055 buddy); | |
1056 presence->u.buddy.ref_count--; | |
1057 } | |
6065 | 1058 } |
1059 | |
9949 | 1060 void |
1061 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
1062 { | |
1063 g_return_if_fail(presence != NULL); | |
1064 g_return_if_fail(status != NULL); | |
1065 | |
1066 presence->statuses = g_list_append(presence->statuses, status); | |
1067 | |
1068 g_hash_table_insert(presence->status_table, | |
1069 g_strdup(gaim_status_get_id(status)), status); | |
1070 } | |
1071 | |
1072 void | |
1073 gaim_presence_add_presence(GaimPresence *presence, const GList *source_list) | |
1074 { | |
1075 const GList *l; | |
1076 | |
1077 g_return_if_fail(presence != NULL); | |
1078 g_return_if_fail(source_list != NULL); | |
1079 | |
1080 for (l = source_list; l != NULL; l = l->next) | |
1081 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
1082 } | |
1083 | |
1084 void | |
1085 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
1086 gboolean active) | |
1087 { | |
1088 GaimStatus *status; | |
1089 | |
1090 g_return_if_fail(presence != NULL); | |
1091 g_return_if_fail(status_id != NULL); | |
1092 | |
1093 status = gaim_presence_get_status(presence, status_id); | |
1094 | |
1095 g_return_if_fail(status != NULL); | |
1096 | |
10067 | 1097 if (gaim_status_is_exclusive(status)) |
9949 | 1098 { |
1099 if (!active) | |
1100 { | |
1101 gaim_debug_warning("status", | |
1102 "Attempted to set a non-independent status " | |
1103 "(%s) inactive. Only independent statuses " | |
1104 "can be specifically marked inactive.", | |
1105 status_id); | |
1106 | |
1107 return; | |
1108 } | |
1109 | |
10052 | 1110 } else if (presence->active_status != NULL) { |
1111 gaim_status_set_active(presence->active_status, FALSE); | |
9949 | 1112 |
1113 } | |
1114 | |
1115 gaim_status_set_active(status, active); | |
10052 | 1116 presence->active_status = status; |
9949 | 1117 } |
1118 | |
1119 void | |
1120 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
1121 { | |
1122 GaimStatus *status; | |
1123 | |
1124 g_return_if_fail(presence != NULL); | |
1125 g_return_if_fail(status_id != NULL); | |
1126 | |
1127 status = gaim_presence_get_status(presence, status_id); | |
1128 | |
1129 g_return_if_fail(status != NULL); | |
1130 | |
1131 if (gaim_status_is_independent(status)) | |
1132 return; | |
1133 | |
1134 if (presence->active_status != NULL) | |
1135 gaim_status_set_active(presence->active_status, FALSE); | |
1136 | |
1137 gaim_status_set_active(status, TRUE); | |
1138 } | |
1139 | |
1140 static void | |
1141 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
1142 time_t current_time, gboolean old_idle, gboolean idle) | |
1143 { | |
1144 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1145 | |
1146 if (!old_idle && idle) | |
1147 { | |
1148 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle", buddy); | |
1149 | |
1150 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1151 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1152 { | |
1153 GaimLog *log = gaim_account_get_log(buddy->account); | |
1154 char *tmp = g_strdup_printf(_("%s became idle"), | |
1155 gaim_buddy_get_alias(buddy)); | |
1156 | |
1157 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1158 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1159 g_free(tmp); | |
1160 } | |
1161 } | |
1162 else if (old_idle && !idle) | |
1163 { | |
1164 gaim_signal_emit(gaim_blist_get_handle(), "buddy-unidle", buddy); | |
1165 | |
1166 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1167 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1168 { | |
1169 GaimLog *log = gaim_account_get_log(buddy->account); | |
1170 char *tmp = g_strdup_printf(_("%s became unidle"), | |
1171 gaim_buddy_get_alias(buddy)); | |
1172 | |
1173 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1174 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1175 g_free(tmp); | |
1176 } | |
1177 } | |
1178 | |
1179 gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); | |
1180 | |
1181 if (ops != NULL && ops->update != NULL) | |
1182 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
1183 } | |
1184 | |
1185 void | |
1186 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
1187 { | |
1188 gboolean old_idle; | |
1189 | |
1190 g_return_if_fail(presence != NULL); | |
1191 | |
1192 if (presence->idle == idle && presence->idle_time == idle_time) | |
1193 return; | |
1194 | |
1195 old_idle = presence->idle; | |
1196 presence->idle = idle; | |
1197 presence->idle_time = (idle ? idle_time : 0); | |
1198 | |
1199 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1200 { | |
1201 const GList *l; | |
1202 time_t current_time = time(NULL); | |
1203 | |
1204 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
1205 { | |
1206 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
1207 old_idle, idle); | |
1208 } | |
1209 } | |
1210 } | |
1211 | |
1212 void | |
10006 | 1213 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
1214 { | |
1215 g_return_if_fail(presence != NULL); | |
1216 | |
1217 if (presence->login_time == login_time) | |
1218 return; | |
1219 | |
1220 presence->login_time = login_time; | |
1221 } | |
1222 | |
1223 void | |
9949 | 1224 gaim_presence_set_warning_level(GaimPresence *presence, unsigned int level) |
6065 | 1225 { |
9949 | 1226 g_return_if_fail(presence != NULL); |
1227 g_return_if_fail(level <= 100); | |
1228 | |
1229 if (presence->warning_level == level) | |
1230 return; | |
1231 | |
1232 presence->warning_level = level; | |
1233 | |
1234 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1235 { | |
1236 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1237 | |
1238 if (ops != NULL && ops->update != NULL) | |
1239 { | |
1240 const GList *l; | |
1241 | |
1242 for (l = gaim_presence_get_buddies(presence); | |
1243 l != NULL; | |
1244 l = l->next) | |
1245 { | |
1246 ops->update(gaim_get_blist(), (GaimBlistNode *)l->data); | |
1247 } | |
1248 } | |
1249 } | |
1250 } | |
1251 | |
1252 GaimPresenceContext | |
1253 gaim_presence_get_context(const GaimPresence *presence) | |
1254 { | |
1255 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
1256 | |
1257 return presence->context; | |
1258 } | |
1259 | |
1260 GaimAccount * | |
1261 gaim_presence_get_account(const GaimPresence *presence) | |
1262 { | |
1263 GaimPresenceContext context; | |
1264 | |
1265 g_return_val_if_fail(presence != NULL, NULL); | |
1266 | |
1267 context = gaim_presence_get_context(presence); | |
1268 | |
1269 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
1270 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1271 | |
1272 return presence->u.account; | |
1273 } | |
1274 | |
1275 GaimConversation * | |
1276 gaim_presence_get_conversation(const GaimPresence *presence) | |
1277 { | |
1278 g_return_val_if_fail(presence != NULL, NULL); | |
1279 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1280 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1281 | |
1282 return presence->u.chat.conv; | |
1283 } | |
1284 | |
1285 const char * | |
1286 gaim_presence_get_chat_user(const GaimPresence *presence) | |
1287 { | |
1288 g_return_val_if_fail(presence != NULL, NULL); | |
1289 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1290 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1291 | |
1292 return presence->u.chat.user; | |
1293 } | |
1294 | |
1295 const GList * | |
1296 gaim_presence_get_buddies(const GaimPresence *presence) | |
1297 { | |
1298 g_return_val_if_fail(presence != NULL, NULL); | |
1299 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1300 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1301 | |
1302 return presence->u.buddy.buddies; | |
1303 } | |
1304 | |
1305 const GList * | |
1306 gaim_presence_get_statuses(const GaimPresence *presence) | |
1307 { | |
1308 g_return_val_if_fail(presence != NULL, NULL); | |
1309 | |
1310 return presence->statuses; | |
1311 } | |
1312 | |
1313 GaimStatus * | |
1314 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
1315 { | |
1316 GaimStatus *status; | |
10006 | 1317 const GList *l = NULL; |
9949 | 1318 |
1319 g_return_val_if_fail(presence != NULL, NULL); | |
1320 g_return_val_if_fail(status_id != NULL, NULL); | |
1321 | |
10006 | 1322 /* What's the purpose of this hash table? */ |
10012 | 1323 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
10006 | 1324 status_id); |
10012 | 1325 |
10006 | 1326 if (status == NULL) { |
10012 | 1327 for (l = gaim_presence_get_statuses(presence); |
10006 | 1328 l != NULL && status == NULL; l = l->next) |
1329 { | |
1330 GaimStatus *temp_status = l->data; | |
10012 | 1331 |
10006 | 1332 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
1333 status = temp_status; | |
1334 } | |
1335 | |
1336 if (status != NULL) | |
1337 g_hash_table_insert(presence->status_table, | |
1338 g_strdup(gaim_status_get_id(status)), status); | |
10012 | 1339 } |
9949 | 1340 |
1341 return status; | |
1342 } | |
1343 | |
1344 GaimStatus * | |
1345 gaim_presence_get_active_status(const GaimPresence *presence) | |
1346 { | |
1347 g_return_val_if_fail(presence != NULL, NULL); | |
1348 | |
1349 return presence->active_status; | |
1350 } | |
1351 | |
1352 gboolean | |
1353 gaim_presence_is_available(const GaimPresence *presence) | |
1354 { | |
1355 GaimStatus *status; | |
1356 | |
1357 g_return_val_if_fail(presence != NULL, FALSE); | |
1358 | |
1359 status = gaim_presence_get_active_status(presence); | |
1360 | |
1361 return ((status != NULL && gaim_status_is_available(status)) && | |
1362 !gaim_presence_is_idle(presence)); | |
1363 } | |
1364 | |
1365 gboolean | |
1366 gaim_presence_is_online(const GaimPresence *presence) | |
1367 { | |
1368 GaimStatus *status; | |
1369 | |
1370 g_return_val_if_fail(presence != NULL, FALSE); | |
1371 | |
1372 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
1373 return FALSE; | |
1374 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1375 return gaim_status_is_online(status); |
9949 | 1376 } |
1377 | |
1378 gboolean | |
1379 gaim_presence_is_status_active(const GaimPresence *presence, | |
1380 const char *status_id) | |
1381 { | |
1382 GaimStatus *status; | |
1383 | |
1384 g_return_val_if_fail(presence != NULL, FALSE); | |
1385 g_return_val_if_fail(status_id != NULL, FALSE); | |
1386 | |
1387 status = gaim_presence_get_status(presence, status_id); | |
1388 | |
1389 return (status != NULL && gaim_status_is_active(status)); | |
1390 } | |
1391 | |
1392 gboolean | |
1393 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
1394 GaimStatusPrimitive primitive) | |
1395 { | |
1396 GaimStatus *status; | |
1397 GaimStatusType *status_type; | |
1398 | |
1399 g_return_val_if_fail(presence != NULL, FALSE); | |
1400 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
1401 | |
1402 status = gaim_presence_get_active_status(presence); | |
1403 status_type = gaim_status_get_type(status); | |
1404 | |
1405 if (gaim_status_type_get_primitive(status_type) == primitive) | |
1406 return TRUE; | |
6065 | 1407 |
1408 return FALSE; | |
1409 } | |
1410 | |
9949 | 1411 gboolean |
1412 gaim_presence_is_idle(const GaimPresence *presence) | |
6065 | 1413 { |
9949 | 1414 g_return_val_if_fail(presence != NULL, FALSE); |
1415 | |
1416 return presence->idle; | |
6065 | 1417 } |
1418 | |
9949 | 1419 time_t |
1420 gaim_presence_get_idle_time(const GaimPresence *presence) | |
6065 | 1421 { |
9949 | 1422 g_return_val_if_fail(presence != NULL, 0); |
6065 | 1423 |
9949 | 1424 return presence->idle_time; |
1425 } | |
6065 | 1426 |
9949 | 1427 unsigned int |
1428 gaim_presence_get_warning_level(const GaimPresence *presence) | |
1429 { | |
1430 g_return_val_if_fail(presence != NULL, 0); | |
6216 | 1431 |
9949 | 1432 return presence->warning_level; |
6065 | 1433 } |
1434 | |
9949 | 1435 gint |
1436 gaim_presence_compare(const GaimPresence *presence1, | |
1437 const GaimPresence *presence2) | |
6065 | 1438 { |
9949 | 1439 gboolean idle1, idle2; |
1440 size_t idle_time_1, idle_time_2; | |
1441 int score1 = 0, score2 = 0; | |
1442 const GList *l; | |
6065 | 1443 |
9949 | 1444 if ((presence1 == NULL && presence2 == NULL) || (presence1 == presence2)) |
1445 return 0; | |
1446 else if (presence1 == NULL) | |
1447 return -1; | |
1448 else if (presence2 == NULL) | |
1449 return 1; | |
6065 | 1450 |
9949 | 1451 /* Compute the score of the first set of statuses. */ |
1452 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1453 { | |
1454 GaimStatus *status = (GaimStatus *)l->data; | |
1455 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1456 |
9949 | 1457 if (gaim_status_is_active(status)) |
1458 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1459 } |
1460 | |
9949 | 1461 /* Compute the score of the second set of statuses. */ |
1462 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1463 { | |
1464 GaimStatus *status = (GaimStatus *)l->data; | |
1465 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1466 |
9949 | 1467 if (gaim_status_is_active(status)) |
1468 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1469 } |
1470 | |
9949 | 1471 idle1 = gaim_presence_is_idle(presence1); |
1472 idle2 = gaim_presence_is_idle(presence2); | |
6065 | 1473 |
9949 | 1474 if (idle1) |
1475 score1 += primitive_scores[SCORE_IDLE]; | |
6065 | 1476 |
9949 | 1477 if (idle2) |
1478 score2 += primitive_scores[SCORE_IDLE]; | |
6065 | 1479 |
9949 | 1480 idle_time_1 = gaim_presence_get_idle_time(presence1); |
1481 idle_time_2 = gaim_presence_get_idle_time(presence2); | |
6065 | 1482 |
9949 | 1483 if (idle_time_1 > idle_time_2) |
1484 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
1485 else if (idle_time_1 < idle_time_2) | |
1486 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
6065 | 1487 |
9949 | 1488 if (score1 < score2) |
1489 return 1; | |
1490 else if (score1 > score2) | |
1491 return -1; | |
1492 | |
1493 return 0; | |
1494 } | |
1495 | |
6065 | 1496 |
9949 | 1497 /************************************************************************** |
1498 * Status subsystem | |
1499 **************************************************************************/ | |
1500 static void | |
1501 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
1502 gpointer data) | |
1503 { | |
1504 int index = GPOINTER_TO_INT(data); | |
6065 | 1505 |
9949 | 1506 primitive_scores[index] = GPOINTER_TO_INT(value); |
6065 | 1507 } |
1508 | |
10012 | 1509 guint |
10006 | 1510 gaim_buddy_presences_hash(gconstpointer key) |
1511 { | |
10012 | 1512 const GaimStatusBuddyKey *me = key; |
1513 guint ret; | |
1514 char *str; | |
1515 | |
1516 str = g_strdup_printf("%p%s", me->account, me->name); | |
1517 ret = g_str_hash(str); | |
1518 g_free(str); | |
1519 | |
1520 return ret; | |
10006 | 1521 } |
1522 | |
10012 | 1523 gboolean |
10006 | 1524 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
1525 { | |
1526 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
1527 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
1528 | |
10012 | 1529 if(key_a->account == key_b->account && |
1530 !strcmp(key_a->name, key_b->name)) | |
10006 | 1531 return TRUE; |
1532 else | |
1533 return FALSE; | |
1534 } | |
1535 | |
10087 | 1536 void * |
1537 gaim_statuses_get_handle() { | |
1538 static int handle; | |
1539 | |
1540 return &handle; | |
1541 } | |
1542 | |
9949 | 1543 void |
1544 gaim_statuses_init(void) | |
6065 | 1545 { |
10087 | 1546 void *handle = gaim_statuses_get_handle; |
1547 | |
9949 | 1548 gaim_prefs_add_none("/core/status"); |
1549 gaim_prefs_add_none("/core/status/scores"); | |
6065 | 1550 |
9949 | 1551 gaim_prefs_add_int("/core/status/scores/offline", |
1552 primitive_scores[GAIM_STATUS_OFFLINE]); | |
1553 gaim_prefs_add_int("/core/status/scores/available", | |
1554 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
1555 gaim_prefs_add_int("/core/status/scores/hidden", | |
1556 primitive_scores[GAIM_STATUS_HIDDEN]); | |
1557 gaim_prefs_add_int("/core/status/scores/away", | |
1558 primitive_scores[GAIM_STATUS_AWAY]); | |
1559 gaim_prefs_add_int("/core/status/scores/extended_away", | |
1560 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
1561 gaim_prefs_add_int("/core/status/scores/idle", | |
1562 primitive_scores[SCORE_IDLE]); | |
6065 | 1563 |
10087 | 1564 gaim_prefs_connect_callback(handle, "/core/status/scores/offline", |
9949 | 1565 score_pref_changed_cb, |
1566 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
10087 | 1567 gaim_prefs_connect_callback(handle, "/core/status/scores/available", |
9949 | 1568 score_pref_changed_cb, |
1569 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
10087 | 1570 gaim_prefs_connect_callback(handle, "/core/status/scores/hidden", |
9949 | 1571 score_pref_changed_cb, |
1572 GINT_TO_POINTER(GAIM_STATUS_HIDDEN)); | |
10087 | 1573 gaim_prefs_connect_callback(handle, "/core/status/scores/away", |
9949 | 1574 score_pref_changed_cb, |
1575 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
10087 | 1576 gaim_prefs_connect_callback(handle, "/core/status/scores/extended_away", |
9949 | 1577 score_pref_changed_cb, |
1578 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
10087 | 1579 gaim_prefs_connect_callback(handle, "/core/status/scores/idle", |
9949 | 1580 score_pref_changed_cb, |
1581 GINT_TO_POINTER(SCORE_IDLE)); | |
10006 | 1582 |
1583 buddy_presences = g_hash_table_new(gaim_buddy_presences_hash, | |
1584 gaim_buddy_presences_equal); | |
9949 | 1585 } |
6065 | 1586 |
9949 | 1587 void |
1588 gaim_statuses_uninit(void) | |
1589 { | |
10077 | 1590 if(buddy_presences != NULL) |
1591 g_hash_table_destroy(buddy_presences); | |
1592 buddy_presences = NULL; | |
9949 | 1593 } |
6065 | 1594 |
9949 | 1595 void |
1596 gaim_statuses_sync(void) | |
1597 { | |
6065 | 1598 } |
9949 | 1599 |
1600 void | |
1601 gaim_statuses_load(void) | |
1602 { | |
1603 } |