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