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