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