/src/pidgin/libpurple/status.c
Line | Count | Source |
1 | | /** |
2 | | * @file status.c Status API |
3 | | * @ingroup core |
4 | | */ |
5 | | |
6 | | /* purple |
7 | | * |
8 | | * Purple is the legal property of its developers, whose names are too numerous |
9 | | * to list here. Please refer to the COPYRIGHT file distributed with this |
10 | | * source distribution. |
11 | | * |
12 | | * This program is free software; you can redistribute it and/or modify |
13 | | * it under the terms of the GNU General Public License as published by |
14 | | * the Free Software Foundation; either version 2 of the License, or |
15 | | * (at your option) any later version. |
16 | | * |
17 | | * This program is distributed in the hope that it will be useful, |
18 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | | * GNU General Public License for more details. |
21 | | * |
22 | | * You should have received a copy of the GNU General Public License |
23 | | * along with this program; if not, write to the Free Software |
24 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
25 | | */ |
26 | | #define _PURPLE_STATUS_C_ |
27 | | |
28 | | #include "internal.h" |
29 | | |
30 | | #include "blist.h" |
31 | | #include "core.h" |
32 | | #include "dbus-maybe.h" |
33 | | #include "debug.h" |
34 | | #include "glibcompat.h" |
35 | | #include "notify.h" |
36 | | #include "prefs.h" |
37 | | #include "status.h" |
38 | | |
39 | | /** |
40 | | * A type of status. |
41 | | */ |
42 | | struct _PurpleStatusType |
43 | | { |
44 | | PurpleStatusPrimitive primitive; |
45 | | |
46 | | char *id; |
47 | | char *name; |
48 | | char *primary_attr_id; |
49 | | |
50 | | gboolean saveable; |
51 | | gboolean user_settable; |
52 | | gboolean independent; |
53 | | |
54 | | GList *attrs; |
55 | | }; |
56 | | |
57 | | /** |
58 | | * A status attribute. |
59 | | */ |
60 | | struct _PurpleStatusAttr |
61 | | { |
62 | | char *id; |
63 | | char *name; |
64 | | PurpleValue *value_type; |
65 | | }; |
66 | | |
67 | | /** |
68 | | * A list of statuses. |
69 | | */ |
70 | | struct _PurplePresence |
71 | | { |
72 | | PurplePresenceContext context; |
73 | | |
74 | | gboolean idle; |
75 | | time_t idle_time; |
76 | | time_t login_time; |
77 | | |
78 | | GList *statuses; |
79 | | GHashTable *status_table; |
80 | | |
81 | | PurpleStatus *active_status; |
82 | | |
83 | | union |
84 | | { |
85 | | PurpleAccount *account; |
86 | | |
87 | | struct |
88 | | { |
89 | | PurpleConversation *conv; |
90 | | char *user; |
91 | | |
92 | | } chat; |
93 | | |
94 | | struct |
95 | | { |
96 | | PurpleAccount *account; |
97 | | char *name; |
98 | | PurpleBuddy *buddy; |
99 | | |
100 | | } buddy; |
101 | | |
102 | | } u; |
103 | | }; |
104 | | |
105 | | /** |
106 | | * An active status. |
107 | | */ |
108 | | struct _PurpleStatus |
109 | | { |
110 | | PurpleStatusType *type; |
111 | | PurplePresence *presence; |
112 | | |
113 | | gboolean active; |
114 | | |
115 | | /* |
116 | | * The current values of the attributes for this status. The |
117 | | * key is a string containing the name of the attribute. It is |
118 | | * a borrowed reference from the list of attrs in the |
119 | | * PurpleStatusType. The value is a PurpleValue. |
120 | | */ |
121 | | GHashTable *attr_values; |
122 | | }; |
123 | | |
124 | | typedef struct |
125 | | { |
126 | | PurpleAccount *account; |
127 | | char *name; |
128 | | } PurpleStatusBuddyKey; |
129 | | |
130 | | static int primitive_scores[] = |
131 | | { |
132 | | 0, /* unset */ |
133 | | -500, /* offline */ |
134 | | 100, /* available */ |
135 | | -75, /* unavailable */ |
136 | | -50, /* invisible */ |
137 | | -100, /* away */ |
138 | | -200, /* extended away */ |
139 | | -400, /* mobile */ |
140 | | 0, /* tune */ |
141 | | 0, /* mood */ |
142 | | -10, /* idle, special case. */ |
143 | | -5, /* idle time, special case. */ |
144 | | 10 /* Offline messageable */ |
145 | | }; |
146 | | |
147 | 0 | #define SCORE_IDLE 9 |
148 | 0 | #define SCORE_IDLE_TIME 10 |
149 | 0 | #define SCORE_OFFLINE_MESSAGE 11 |
150 | | |
151 | | /************************************************************************** |
152 | | * PurpleStatusPrimitive API |
153 | | **************************************************************************/ |
154 | | static struct PurpleStatusPrimitiveMap |
155 | | { |
156 | | PurpleStatusPrimitive type; |
157 | | const char *id; |
158 | | const char *name; |
159 | | |
160 | | } const status_primitive_map[] = |
161 | | { |
162 | | { PURPLE_STATUS_UNSET, "unset", N_("Unset") }, |
163 | | { PURPLE_STATUS_OFFLINE, "offline", N_("Offline") }, |
164 | | { PURPLE_STATUS_AVAILABLE, "available", N_("Available") }, |
165 | | { PURPLE_STATUS_UNAVAILABLE, "unavailable", N_("Do not disturb") }, |
166 | | { PURPLE_STATUS_INVISIBLE, "invisible", N_("Invisible") }, |
167 | | { PURPLE_STATUS_AWAY, "away", N_("Away") }, |
168 | | { PURPLE_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended away") }, |
169 | | { PURPLE_STATUS_MOBILE, "mobile", N_("Mobile") }, |
170 | | { PURPLE_STATUS_TUNE, "tune", N_("Listening to music"), }, |
171 | | { PURPLE_STATUS_MOOD, "mood", N_("Feeling") }, |
172 | | }; |
173 | | |
174 | | const char * |
175 | | purple_primitive_get_id_from_type(PurpleStatusPrimitive type) |
176 | 0 | { |
177 | 0 | int i; |
178 | |
|
179 | 0 | for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) |
180 | 0 | { |
181 | 0 | if (type == status_primitive_map[i].type) |
182 | 0 | return status_primitive_map[i].id; |
183 | 0 | } |
184 | | |
185 | 0 | return status_primitive_map[0].id; |
186 | 0 | } |
187 | | |
188 | | const char * |
189 | | purple_primitive_get_name_from_type(PurpleStatusPrimitive type) |
190 | 0 | { |
191 | 0 | int i; |
192 | |
|
193 | 0 | for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) |
194 | 0 | { |
195 | 0 | if (type == status_primitive_map[i].type) |
196 | 0 | return _(status_primitive_map[i].name); |
197 | 0 | } |
198 | | |
199 | 0 | return _(status_primitive_map[0].name); |
200 | 0 | } |
201 | | |
202 | | PurpleStatusPrimitive |
203 | | purple_primitive_get_type_from_id(const char *id) |
204 | 0 | { |
205 | 0 | int i; |
206 | |
|
207 | 0 | g_return_val_if_fail(id != NULL, PURPLE_STATUS_UNSET); |
208 | | |
209 | 0 | for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) |
210 | 0 | { |
211 | 0 | if (purple_strequal(id, status_primitive_map[i].id)) |
212 | 0 | return status_primitive_map[i].type; |
213 | 0 | } |
214 | | |
215 | 0 | return status_primitive_map[0].type; |
216 | 0 | } |
217 | | |
218 | | |
219 | | /************************************************************************** |
220 | | * PurpleStatusType API |
221 | | **************************************************************************/ |
222 | | PurpleStatusType * |
223 | | purple_status_type_new_full(PurpleStatusPrimitive primitive, const char *id, |
224 | | const char *name, gboolean saveable, |
225 | | gboolean user_settable, gboolean independent) |
226 | 0 | { |
227 | 0 | PurpleStatusType *status_type; |
228 | |
|
229 | 0 | g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); |
230 | | |
231 | 0 | status_type = g_new0(PurpleStatusType, 1); |
232 | 0 | PURPLE_DBUS_REGISTER_POINTER(status_type, PurpleStatusType); |
233 | |
|
234 | 0 | status_type->primitive = primitive; |
235 | 0 | status_type->saveable = saveable; |
236 | 0 | status_type->user_settable = user_settable; |
237 | 0 | status_type->independent = independent; |
238 | |
|
239 | 0 | if (id != NULL) |
240 | 0 | status_type->id = g_strdup(id); |
241 | 0 | else |
242 | 0 | status_type->id = g_strdup(purple_primitive_get_id_from_type(primitive)); |
243 | |
|
244 | 0 | if (name != NULL) |
245 | 0 | status_type->name = g_strdup(name); |
246 | 0 | else |
247 | 0 | status_type->name = g_strdup(purple_primitive_get_name_from_type(primitive)); |
248 | |
|
249 | 0 | return status_type; |
250 | 0 | } |
251 | | |
252 | | PurpleStatusType * |
253 | | purple_status_type_new(PurpleStatusPrimitive primitive, const char *id, |
254 | | const char *name, gboolean user_settable) |
255 | 0 | { |
256 | 0 | g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); |
257 | | |
258 | 0 | return purple_status_type_new_full(primitive, id, name, TRUE, |
259 | 0 | user_settable, FALSE); |
260 | 0 | } |
261 | | |
262 | | PurpleStatusType * |
263 | | purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive, |
264 | | const char *id, const char *name, |
265 | | gboolean saveable, gboolean user_settable, |
266 | | gboolean independent, const char *attr_id, |
267 | | const char *attr_name, PurpleValue *attr_value, |
268 | | ...) |
269 | 0 | { |
270 | 0 | PurpleStatusType *status_type; |
271 | 0 | va_list args; |
272 | |
|
273 | 0 | g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); |
274 | 0 | g_return_val_if_fail(attr_id != NULL, NULL); |
275 | 0 | g_return_val_if_fail(attr_name != NULL, NULL); |
276 | 0 | g_return_val_if_fail(attr_value != NULL, NULL); |
277 | | |
278 | 0 | status_type = purple_status_type_new_full(primitive, id, name, saveable, |
279 | 0 | user_settable, independent); |
280 | | |
281 | | /* Add the first attribute */ |
282 | 0 | purple_status_type_add_attr(status_type, attr_id, attr_name, attr_value); |
283 | |
|
284 | 0 | va_start(args, attr_value); |
285 | 0 | purple_status_type_add_attrs_vargs(status_type, args); |
286 | 0 | va_end(args); |
287 | |
|
288 | 0 | return status_type; |
289 | 0 | } |
290 | | |
291 | | void |
292 | | purple_status_type_destroy(PurpleStatusType *status_type) |
293 | 0 | { |
294 | 0 | g_return_if_fail(status_type != NULL); |
295 | | |
296 | 0 | g_free(status_type->id); |
297 | 0 | g_free(status_type->name); |
298 | 0 | g_free(status_type->primary_attr_id); |
299 | |
|
300 | 0 | g_list_free_full(status_type->attrs, |
301 | 0 | (GDestroyNotify)purple_status_attr_destroy); |
302 | |
|
303 | 0 | PURPLE_DBUS_UNREGISTER_POINTER(status_type); |
304 | 0 | g_free(status_type); |
305 | 0 | } |
306 | | |
307 | | void |
308 | | purple_status_type_set_primary_attr(PurpleStatusType *status_type, const char *id) |
309 | 0 | { |
310 | 0 | g_return_if_fail(status_type != NULL); |
311 | | |
312 | 0 | g_free(status_type->primary_attr_id); |
313 | 0 | status_type->primary_attr_id = g_strdup(id); |
314 | 0 | } |
315 | | |
316 | | void |
317 | | purple_status_type_add_attr(PurpleStatusType *status_type, const char *id, |
318 | | const char *name, PurpleValue *value) |
319 | 0 | { |
320 | 0 | PurpleStatusAttr *attr; |
321 | |
|
322 | 0 | g_return_if_fail(status_type != NULL); |
323 | 0 | g_return_if_fail(id != NULL); |
324 | 0 | g_return_if_fail(name != NULL); |
325 | 0 | g_return_if_fail(value != NULL); |
326 | | |
327 | 0 | attr = purple_status_attr_new(id, name, value); |
328 | |
|
329 | 0 | status_type->attrs = g_list_append(status_type->attrs, attr); |
330 | 0 | } |
331 | | |
332 | | void |
333 | | purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args) |
334 | 0 | { |
335 | 0 | const char *id, *name; |
336 | 0 | PurpleValue *value; |
337 | |
|
338 | 0 | g_return_if_fail(status_type != NULL); |
339 | | |
340 | 0 | while ((id = va_arg(args, const char *)) != NULL) |
341 | 0 | { |
342 | 0 | name = va_arg(args, const char *); |
343 | 0 | g_return_if_fail(name != NULL); |
344 | | |
345 | 0 | value = va_arg(args, PurpleValue *); |
346 | 0 | g_return_if_fail(value != NULL); |
347 | | |
348 | 0 | purple_status_type_add_attr(status_type, id, name, value); |
349 | 0 | } |
350 | 0 | } |
351 | | |
352 | | void |
353 | | purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id, |
354 | | const char *name, PurpleValue *value, ...) |
355 | 0 | { |
356 | 0 | va_list args; |
357 | |
|
358 | 0 | g_return_if_fail(status_type != NULL); |
359 | 0 | g_return_if_fail(id != NULL); |
360 | 0 | g_return_if_fail(name != NULL); |
361 | 0 | g_return_if_fail(value != NULL); |
362 | | |
363 | | /* Add the first attribute */ |
364 | 0 | purple_status_type_add_attr(status_type, id, name, value); |
365 | |
|
366 | 0 | va_start(args, value); |
367 | 0 | purple_status_type_add_attrs_vargs(status_type, args); |
368 | 0 | va_end(args); |
369 | 0 | } |
370 | | |
371 | | PurpleStatusPrimitive |
372 | | purple_status_type_get_primitive(const PurpleStatusType *status_type) |
373 | 0 | { |
374 | 0 | g_return_val_if_fail(status_type != NULL, PURPLE_STATUS_UNSET); |
375 | | |
376 | 0 | return status_type->primitive; |
377 | 0 | } |
378 | | |
379 | | const char * |
380 | | purple_status_type_get_id(const PurpleStatusType *status_type) |
381 | 0 | { |
382 | 0 | g_return_val_if_fail(status_type != NULL, NULL); |
383 | | |
384 | 0 | return status_type->id; |
385 | 0 | } |
386 | | |
387 | | const char * |
388 | | purple_status_type_get_name(const PurpleStatusType *status_type) |
389 | 0 | { |
390 | 0 | g_return_val_if_fail(status_type != NULL, NULL); |
391 | | |
392 | 0 | return status_type->name; |
393 | 0 | } |
394 | | |
395 | | gboolean |
396 | | purple_status_type_is_saveable(const PurpleStatusType *status_type) |
397 | 0 | { |
398 | 0 | g_return_val_if_fail(status_type != NULL, FALSE); |
399 | | |
400 | 0 | return status_type->saveable; |
401 | 0 | } |
402 | | |
403 | | gboolean |
404 | | purple_status_type_is_user_settable(const PurpleStatusType *status_type) |
405 | 0 | { |
406 | 0 | g_return_val_if_fail(status_type != NULL, FALSE); |
407 | | |
408 | 0 | return status_type->user_settable; |
409 | 0 | } |
410 | | |
411 | | gboolean |
412 | | purple_status_type_is_independent(const PurpleStatusType *status_type) |
413 | 0 | { |
414 | 0 | g_return_val_if_fail(status_type != NULL, FALSE); |
415 | | |
416 | 0 | return status_type->independent; |
417 | 0 | } |
418 | | |
419 | | gboolean |
420 | | purple_status_type_is_exclusive(const PurpleStatusType *status_type) |
421 | 0 | { |
422 | 0 | g_return_val_if_fail(status_type != NULL, FALSE); |
423 | | |
424 | 0 | return !status_type->independent; |
425 | 0 | } |
426 | | |
427 | | gboolean |
428 | | purple_status_type_is_available(const PurpleStatusType *status_type) |
429 | 0 | { |
430 | 0 | PurpleStatusPrimitive primitive; |
431 | |
|
432 | 0 | g_return_val_if_fail(status_type != NULL, FALSE); |
433 | | |
434 | 0 | primitive = purple_status_type_get_primitive(status_type); |
435 | |
|
436 | 0 | return (primitive == PURPLE_STATUS_AVAILABLE); |
437 | 0 | } |
438 | | |
439 | | const char * |
440 | | purple_status_type_get_primary_attr(const PurpleStatusType *status_type) |
441 | 0 | { |
442 | 0 | g_return_val_if_fail(status_type != NULL, NULL); |
443 | | |
444 | 0 | return status_type->primary_attr_id; |
445 | 0 | } |
446 | | |
447 | | PurpleStatusAttr * |
448 | | purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id) |
449 | 0 | { |
450 | 0 | GList *l; |
451 | |
|
452 | 0 | g_return_val_if_fail(status_type != NULL, NULL); |
453 | 0 | g_return_val_if_fail(id != NULL, NULL); |
454 | | |
455 | 0 | for (l = status_type->attrs; l != NULL; l = l->next) |
456 | 0 | { |
457 | 0 | PurpleStatusAttr *attr = (PurpleStatusAttr *)l->data; |
458 | |
|
459 | 0 | if (purple_strequal(purple_status_attr_get_id(attr), id)) |
460 | 0 | return attr; |
461 | 0 | } |
462 | | |
463 | 0 | return NULL; |
464 | 0 | } |
465 | | |
466 | | GList * |
467 | | purple_status_type_get_attrs(const PurpleStatusType *status_type) |
468 | 0 | { |
469 | 0 | g_return_val_if_fail(status_type != NULL, NULL); |
470 | | |
471 | 0 | return status_type->attrs; |
472 | 0 | } |
473 | | |
474 | | const PurpleStatusType * |
475 | | purple_status_type_find_with_id(GList *status_types, const char *id) |
476 | 0 | { |
477 | 0 | PurpleStatusType *status_type; |
478 | |
|
479 | 0 | g_return_val_if_fail(id != NULL, NULL); |
480 | | |
481 | 0 | while (status_types != NULL) |
482 | 0 | { |
483 | 0 | status_type = status_types->data; |
484 | |
|
485 | 0 | if (purple_strequal(id, status_type->id)) |
486 | 0 | return status_type; |
487 | | |
488 | 0 | status_types = status_types->next; |
489 | 0 | } |
490 | | |
491 | 0 | return NULL; |
492 | 0 | } |
493 | | |
494 | | |
495 | | /************************************************************************** |
496 | | * PurpleStatusAttr API |
497 | | **************************************************************************/ |
498 | | PurpleStatusAttr * |
499 | | purple_status_attr_new(const char *id, const char *name, PurpleValue *value_type) |
500 | 0 | { |
501 | 0 | PurpleStatusAttr *attr; |
502 | |
|
503 | 0 | g_return_val_if_fail(id != NULL, NULL); |
504 | 0 | g_return_val_if_fail(name != NULL, NULL); |
505 | 0 | g_return_val_if_fail(value_type != NULL, NULL); |
506 | | |
507 | 0 | attr = g_new0(PurpleStatusAttr, 1); |
508 | 0 | PURPLE_DBUS_REGISTER_POINTER(attr, PurpleStatusAttr); |
509 | |
|
510 | 0 | attr->id = g_strdup(id); |
511 | 0 | attr->name = g_strdup(name); |
512 | 0 | attr->value_type = value_type; |
513 | |
|
514 | 0 | return attr; |
515 | 0 | } |
516 | | |
517 | | void |
518 | | purple_status_attr_destroy(PurpleStatusAttr *attr) |
519 | 0 | { |
520 | 0 | g_return_if_fail(attr != NULL); |
521 | | |
522 | 0 | g_free(attr->id); |
523 | 0 | g_free(attr->name); |
524 | |
|
525 | 0 | purple_value_destroy(attr->value_type); |
526 | |
|
527 | 0 | PURPLE_DBUS_UNREGISTER_POINTER(attr); |
528 | 0 | g_free(attr); |
529 | 0 | } |
530 | | |
531 | | const char * |
532 | | purple_status_attr_get_id(const PurpleStatusAttr *attr) |
533 | 0 | { |
534 | 0 | g_return_val_if_fail(attr != NULL, NULL); |
535 | | |
536 | 0 | return attr->id; |
537 | 0 | } |
538 | | |
539 | | const char * |
540 | | purple_status_attr_get_name(const PurpleStatusAttr *attr) |
541 | 0 | { |
542 | 0 | g_return_val_if_fail(attr != NULL, NULL); |
543 | | |
544 | 0 | return attr->name; |
545 | 0 | } |
546 | | |
547 | | PurpleValue * |
548 | | purple_status_attr_get_value(const PurpleStatusAttr *attr) |
549 | 0 | { |
550 | 0 | g_return_val_if_fail(attr != NULL, NULL); |
551 | | |
552 | 0 | return attr->value_type; |
553 | 0 | } |
554 | | |
555 | | |
556 | | /************************************************************************** |
557 | | * PurpleStatus API |
558 | | **************************************************************************/ |
559 | | PurpleStatus * |
560 | | purple_status_new(PurpleStatusType *status_type, PurplePresence *presence) |
561 | 0 | { |
562 | 0 | PurpleStatus *status; |
563 | 0 | GList *l; |
564 | |
|
565 | 0 | g_return_val_if_fail(status_type != NULL, NULL); |
566 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
567 | | |
568 | 0 | status = g_new0(PurpleStatus, 1); |
569 | 0 | PURPLE_DBUS_REGISTER_POINTER(status, PurpleStatus); |
570 | |
|
571 | 0 | status->type = status_type; |
572 | 0 | status->presence = presence; |
573 | |
|
574 | 0 | status->attr_values = |
575 | 0 | g_hash_table_new_full(g_str_hash, g_str_equal, NULL, |
576 | 0 | (GDestroyNotify)purple_value_destroy); |
577 | |
|
578 | 0 | for (l = purple_status_type_get_attrs(status_type); l != NULL; l = l->next) |
579 | 0 | { |
580 | 0 | PurpleStatusAttr *attr = (PurpleStatusAttr *)l->data; |
581 | 0 | PurpleValue *value = purple_status_attr_get_value(attr); |
582 | 0 | PurpleValue *new_value = purple_value_dup(value); |
583 | |
|
584 | 0 | g_hash_table_insert(status->attr_values, |
585 | 0 | (char *)purple_status_attr_get_id(attr), |
586 | 0 | new_value); |
587 | 0 | } |
588 | |
|
589 | 0 | return status; |
590 | 0 | } |
591 | | |
592 | | /* |
593 | | * TODO: If the PurpleStatus is in a PurplePresence, then |
594 | | * remove it from the PurplePresence? |
595 | | */ |
596 | | void |
597 | | purple_status_destroy(PurpleStatus *status) |
598 | 0 | { |
599 | 0 | g_return_if_fail(status != NULL); |
600 | | |
601 | 0 | g_hash_table_destroy(status->attr_values); |
602 | |
|
603 | 0 | PURPLE_DBUS_UNREGISTER_POINTER(status); |
604 | 0 | g_free(status); |
605 | 0 | } |
606 | | |
607 | | static void |
608 | | notify_buddy_status_update(PurpleBuddy *buddy, PurplePresence *presence, |
609 | | PurpleStatus *old_status, PurpleStatus *new_status) |
610 | 0 | { |
611 | 0 | if (purple_prefs_get_bool("/purple/logging/log_system")) |
612 | 0 | { |
613 | 0 | time_t current_time = time(NULL); |
614 | 0 | const char *buddy_alias = purple_buddy_get_alias(buddy); |
615 | 0 | char *tmp, *logtmp; |
616 | 0 | PurpleLog *log; |
617 | |
|
618 | 0 | if (old_status != NULL) |
619 | 0 | { |
620 | 0 | tmp = g_strdup_printf(_("%s (%s) changed status from %s to %s"), buddy_alias, |
621 | 0 | purple_buddy_get_name(buddy), |
622 | 0 | purple_status_get_name(old_status), |
623 | 0 | purple_status_get_name(new_status)); |
624 | 0 | logtmp = g_markup_escape_text(tmp, -1); |
625 | 0 | } |
626 | 0 | else |
627 | 0 | { |
628 | | /* old_status == NULL when an independent status is toggled. */ |
629 | |
|
630 | 0 | if (purple_status_is_active(new_status)) |
631 | 0 | { |
632 | 0 | tmp = g_strdup_printf(_("%s (%s) is now %s"), buddy_alias, |
633 | 0 | purple_buddy_get_name(buddy), |
634 | 0 | purple_status_get_name(new_status)); |
635 | 0 | logtmp = g_markup_escape_text(tmp, -1); |
636 | 0 | } |
637 | 0 | else |
638 | 0 | { |
639 | 0 | tmp = g_strdup_printf(_("%s (%s) is no longer %s"), buddy_alias, |
640 | 0 | purple_buddy_get_name(buddy), |
641 | 0 | purple_status_get_name(new_status)); |
642 | 0 | logtmp = g_markup_escape_text(tmp, -1); |
643 | 0 | } |
644 | 0 | } |
645 | |
|
646 | 0 | log = purple_account_get_log(purple_buddy_get_account(buddy), FALSE); |
647 | 0 | if (log != NULL) |
648 | 0 | { |
649 | 0 | purple_log_write(log, PURPLE_MESSAGE_SYSTEM, buddy_alias, |
650 | 0 | current_time, logtmp); |
651 | 0 | } |
652 | |
|
653 | 0 | g_free(tmp); |
654 | 0 | g_free(logtmp); |
655 | 0 | } |
656 | 0 | } |
657 | | |
658 | | static void |
659 | | notify_status_update(PurplePresence *presence, PurpleStatus *old_status, |
660 | | PurpleStatus *new_status) |
661 | 0 | { |
662 | 0 | PurplePresenceContext context = purple_presence_get_context(presence); |
663 | |
|
664 | 0 | if (context == PURPLE_PRESENCE_CONTEXT_ACCOUNT) |
665 | 0 | { |
666 | 0 | PurpleAccount *account = purple_presence_get_account(presence); |
667 | 0 | PurpleAccountUiOps *ops = purple_accounts_get_ui_ops(); |
668 | |
|
669 | 0 | if (purple_account_get_enabled(account, purple_core_get_ui())) |
670 | 0 | purple_prpl_change_account_status(account, old_status, new_status); |
671 | |
|
672 | 0 | if (ops != NULL && ops->status_changed != NULL) |
673 | 0 | { |
674 | 0 | ops->status_changed(account, new_status); |
675 | 0 | } |
676 | 0 | } |
677 | 0 | else if (context == PURPLE_PRESENCE_CONTEXT_BUDDY) |
678 | 0 | { |
679 | 0 | notify_buddy_status_update(purple_presence_get_buddy(presence), presence, |
680 | 0 | old_status, new_status); |
681 | 0 | } |
682 | 0 | } |
683 | | |
684 | | static void |
685 | | status_has_changed(PurpleStatus *status) |
686 | 0 | { |
687 | 0 | PurplePresence *presence; |
688 | 0 | PurpleStatus *old_status; |
689 | |
|
690 | 0 | presence = purple_status_get_presence(status); |
691 | | |
692 | | /* |
693 | | * If this status is exclusive, then we must be setting it to "active." |
694 | | * Since we are setting it to active, we want to set the currently |
695 | | * active status to "inactive." |
696 | | */ |
697 | 0 | if (purple_status_is_exclusive(status)) |
698 | 0 | { |
699 | 0 | old_status = purple_presence_get_active_status(presence); |
700 | 0 | if (old_status != NULL && (old_status != status)) |
701 | 0 | old_status->active = FALSE; |
702 | 0 | presence->active_status = status; |
703 | 0 | } |
704 | 0 | else |
705 | 0 | old_status = NULL; |
706 | |
|
707 | 0 | notify_status_update(presence, old_status, status); |
708 | 0 | } |
709 | | |
710 | | void |
711 | | purple_status_set_active(PurpleStatus *status, gboolean active) |
712 | 0 | { |
713 | 0 | purple_status_set_active_with_attrs_list(status, active, NULL); |
714 | 0 | } |
715 | | |
716 | | /* |
717 | | * This used to parse the va_list directly, but now it creates a GList |
718 | | * and passes it to purple_status_set_active_with_attrs_list(). That |
719 | | * function was created because accounts.c needs to pass a GList of |
720 | | * attributes to the status API. |
721 | | */ |
722 | | void |
723 | | purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active, va_list args) |
724 | 0 | { |
725 | 0 | GList *attrs = NULL; |
726 | 0 | const gchar *id; |
727 | 0 | gpointer data; |
728 | |
|
729 | 0 | while ((id = va_arg(args, const char *)) != NULL) |
730 | 0 | { |
731 | 0 | attrs = g_list_append(attrs, (char *)id); |
732 | 0 | data = va_arg(args, void *); |
733 | 0 | attrs = g_list_append(attrs, data); |
734 | 0 | } |
735 | 0 | purple_status_set_active_with_attrs_list(status, active, attrs); |
736 | 0 | g_list_free(attrs); |
737 | 0 | } |
738 | | |
739 | | void |
740 | | purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active, |
741 | | GList *attrs) |
742 | 0 | { |
743 | 0 | gboolean changed = FALSE; |
744 | 0 | GList *l; |
745 | 0 | GList *specified_attr_ids = NULL; |
746 | 0 | PurpleStatusType *status_type; |
747 | |
|
748 | 0 | g_return_if_fail(status != NULL); |
749 | | |
750 | 0 | if (!active && purple_status_is_exclusive(status)) |
751 | 0 | { |
752 | 0 | purple_debug_error("status", |
753 | 0 | "Cannot deactivate an exclusive status (%s).\n", |
754 | 0 | purple_status_get_id(status)); |
755 | 0 | return; |
756 | 0 | } |
757 | | |
758 | 0 | if (status->active != active) |
759 | 0 | { |
760 | 0 | changed = TRUE; |
761 | 0 | } |
762 | |
|
763 | 0 | status->active = active; |
764 | | |
765 | | /* Set any attributes */ |
766 | 0 | l = attrs; |
767 | 0 | while (l != NULL) |
768 | 0 | { |
769 | 0 | const gchar *id; |
770 | 0 | PurpleValue *value; |
771 | |
|
772 | 0 | id = l->data; |
773 | 0 | l = l->next; |
774 | 0 | value = purple_status_get_attr_value(status, id); |
775 | 0 | if (value == NULL) |
776 | 0 | { |
777 | 0 | purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " |
778 | 0 | "not supported.\n", id, status->type->name); |
779 | | /* Skip over the data and move on to the next attribute */ |
780 | 0 | l = l->next; |
781 | 0 | continue; |
782 | 0 | } |
783 | | |
784 | 0 | specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id); |
785 | |
|
786 | 0 | if (value->type == PURPLE_TYPE_STRING) |
787 | 0 | { |
788 | 0 | const gchar *string_data = l->data; |
789 | 0 | l = l->next; |
790 | 0 | if (purple_strequal(string_data, value->data.string_data)) |
791 | 0 | continue; |
792 | 0 | purple_status_set_attr_string(status, id, string_data); |
793 | 0 | changed = TRUE; |
794 | 0 | } |
795 | 0 | else if (value->type == PURPLE_TYPE_INT) |
796 | 0 | { |
797 | 0 | int int_data = GPOINTER_TO_INT(l->data); |
798 | 0 | l = l->next; |
799 | 0 | if (int_data == value->data.int_data) |
800 | 0 | continue; |
801 | 0 | purple_status_set_attr_int(status, id, int_data); |
802 | 0 | changed = TRUE; |
803 | 0 | } |
804 | 0 | else if (value->type == PURPLE_TYPE_BOOLEAN) |
805 | 0 | { |
806 | 0 | gboolean boolean_data = GPOINTER_TO_INT(l->data); |
807 | 0 | l = l->next; |
808 | 0 | if (boolean_data == value->data.boolean_data) |
809 | 0 | continue; |
810 | 0 | purple_status_set_attr_boolean(status, id, boolean_data); |
811 | 0 | changed = TRUE; |
812 | 0 | } |
813 | 0 | else |
814 | 0 | { |
815 | | /* We don't know what the data is--skip over it */ |
816 | 0 | l = l->next; |
817 | 0 | } |
818 | 0 | } |
819 | | |
820 | | /* Reset any unspecified attributes to their default value */ |
821 | 0 | status_type = purple_status_get_type(status); |
822 | 0 | l = purple_status_type_get_attrs(status_type); |
823 | 0 | while (l != NULL) { |
824 | 0 | PurpleStatusAttr *attr; |
825 | |
|
826 | 0 | attr = l->data; |
827 | 0 | l = l->next; |
828 | |
|
829 | 0 | if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) { |
830 | 0 | PurpleValue *default_value; |
831 | 0 | default_value = purple_status_attr_get_value(attr); |
832 | 0 | if (default_value->type == PURPLE_TYPE_STRING) { |
833 | 0 | const char *cur = purple_status_get_attr_string(status, attr->id); |
834 | 0 | const char *def = purple_value_get_string(default_value); |
835 | 0 | if (purple_strequal(cur, def)) { |
836 | 0 | continue; |
837 | 0 | } |
838 | | |
839 | 0 | purple_status_set_attr_string(status, attr->id, def); |
840 | 0 | } else if (default_value->type == PURPLE_TYPE_INT) { |
841 | 0 | int cur = purple_status_get_attr_int(status, attr->id); |
842 | 0 | int def = purple_value_get_int(default_value); |
843 | 0 | if (cur == def) |
844 | 0 | continue; |
845 | | |
846 | 0 | purple_status_set_attr_int(status, attr->id, def); |
847 | 0 | } else if (default_value->type == PURPLE_TYPE_BOOLEAN) { |
848 | 0 | gboolean cur = purple_status_get_attr_boolean(status, attr->id); |
849 | 0 | gboolean def = purple_value_get_boolean(default_value); |
850 | 0 | if (cur == def) |
851 | 0 | continue; |
852 | | |
853 | 0 | purple_status_set_attr_boolean(status, attr->id, def); |
854 | 0 | } |
855 | 0 | changed = TRUE; |
856 | 0 | } |
857 | 0 | } |
858 | 0 | g_list_free(specified_attr_ids); |
859 | |
|
860 | 0 | if (!changed) |
861 | 0 | return; |
862 | 0 | status_has_changed(status); |
863 | 0 | } |
864 | | |
865 | | void |
866 | | purple_status_set_attr_boolean(PurpleStatus *status, const char *id, |
867 | | gboolean value) |
868 | 0 | { |
869 | 0 | PurpleValue *attr_value; |
870 | |
|
871 | 0 | g_return_if_fail(status != NULL); |
872 | 0 | g_return_if_fail(id != NULL); |
873 | | |
874 | | /* Make sure this attribute exists and is the correct type. */ |
875 | 0 | attr_value = purple_status_get_attr_value(status, id); |
876 | 0 | g_return_if_fail(attr_value != NULL); |
877 | 0 | g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN); |
878 | | |
879 | 0 | purple_value_set_boolean(attr_value, value); |
880 | 0 | } |
881 | | |
882 | | void |
883 | | purple_status_set_attr_int(PurpleStatus *status, const char *id, int value) |
884 | 0 | { |
885 | 0 | PurpleValue *attr_value; |
886 | |
|
887 | 0 | g_return_if_fail(status != NULL); |
888 | 0 | g_return_if_fail(id != NULL); |
889 | | |
890 | | /* Make sure this attribute exists and is the correct type. */ |
891 | 0 | attr_value = purple_status_get_attr_value(status, id); |
892 | 0 | g_return_if_fail(attr_value != NULL); |
893 | 0 | g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT); |
894 | | |
895 | 0 | purple_value_set_int(attr_value, value); |
896 | 0 | } |
897 | | |
898 | | void |
899 | | purple_status_set_attr_string(PurpleStatus *status, const char *id, |
900 | | const char *value) |
901 | 0 | { |
902 | 0 | PurpleValue *attr_value; |
903 | |
|
904 | 0 | g_return_if_fail(status != NULL); |
905 | 0 | g_return_if_fail(id != NULL); |
906 | | |
907 | | /* Make sure this attribute exists and is the correct type. */ |
908 | 0 | attr_value = purple_status_get_attr_value(status, id); |
909 | | /* This used to be g_return_if_fail, but it's failing a LOT, so |
910 | | * let's generate a log error for now. */ |
911 | | /* g_return_if_fail(attr_value != NULL); */ |
912 | 0 | if (attr_value == NULL) { |
913 | 0 | purple_debug_error("status", |
914 | 0 | "Attempted to set status attribute '%s' for " |
915 | 0 | "status '%s', which is not legal. Fix " |
916 | 0 | "this!\n", id, |
917 | 0 | purple_status_type_get_name(purple_status_get_type(status))); |
918 | 0 | return; |
919 | 0 | } |
920 | 0 | g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_STRING); |
921 | | |
922 | | /* XXX: Check if the value has actually changed. If it has, and the status |
923 | | * is active, should this trigger 'status_has_changed'? */ |
924 | 0 | purple_value_set_string(attr_value, value); |
925 | 0 | } |
926 | | |
927 | | PurpleStatusType * |
928 | | purple_status_get_type(const PurpleStatus *status) |
929 | 0 | { |
930 | 0 | g_return_val_if_fail(status != NULL, NULL); |
931 | | |
932 | 0 | return status->type; |
933 | 0 | } |
934 | | |
935 | | PurplePresence * |
936 | | purple_status_get_presence(const PurpleStatus *status) |
937 | 0 | { |
938 | 0 | g_return_val_if_fail(status != NULL, NULL); |
939 | | |
940 | 0 | return status->presence; |
941 | 0 | } |
942 | | |
943 | | const char * |
944 | | purple_status_get_id(const PurpleStatus *status) |
945 | 0 | { |
946 | 0 | g_return_val_if_fail(status != NULL, NULL); |
947 | | |
948 | 0 | return purple_status_type_get_id(purple_status_get_type(status)); |
949 | 0 | } |
950 | | |
951 | | const char * |
952 | | purple_status_get_name(const PurpleStatus *status) |
953 | 0 | { |
954 | 0 | g_return_val_if_fail(status != NULL, NULL); |
955 | | |
956 | 0 | return purple_status_type_get_name(purple_status_get_type(status)); |
957 | 0 | } |
958 | | |
959 | | gboolean |
960 | | purple_status_is_independent(const PurpleStatus *status) |
961 | 0 | { |
962 | 0 | g_return_val_if_fail(status != NULL, FALSE); |
963 | | |
964 | 0 | return purple_status_type_is_independent(purple_status_get_type(status)); |
965 | 0 | } |
966 | | |
967 | | gboolean |
968 | | purple_status_is_exclusive(const PurpleStatus *status) |
969 | 0 | { |
970 | 0 | g_return_val_if_fail(status != NULL, FALSE); |
971 | | |
972 | 0 | return purple_status_type_is_exclusive(purple_status_get_type(status)); |
973 | 0 | } |
974 | | |
975 | | gboolean |
976 | | purple_status_is_available(const PurpleStatus *status) |
977 | 0 | { |
978 | 0 | g_return_val_if_fail(status != NULL, FALSE); |
979 | | |
980 | 0 | return purple_status_type_is_available(purple_status_get_type(status)); |
981 | 0 | } |
982 | | |
983 | | gboolean |
984 | | purple_status_is_active(const PurpleStatus *status) |
985 | 0 | { |
986 | 0 | g_return_val_if_fail(status != NULL, FALSE); |
987 | | |
988 | 0 | return status->active; |
989 | 0 | } |
990 | | |
991 | | gboolean |
992 | | purple_status_is_online(const PurpleStatus *status) |
993 | 0 | { |
994 | 0 | PurpleStatusPrimitive primitive; |
995 | |
|
996 | 0 | g_return_val_if_fail( status != NULL, FALSE); |
997 | | |
998 | 0 | primitive = purple_status_type_get_primitive(purple_status_get_type(status)); |
999 | |
|
1000 | 0 | return (primitive != PURPLE_STATUS_UNSET && |
1001 | 0 | primitive != PURPLE_STATUS_OFFLINE); |
1002 | 0 | } |
1003 | | |
1004 | | PurpleValue * |
1005 | | purple_status_get_attr_value(const PurpleStatus *status, const char *id) |
1006 | 0 | { |
1007 | 0 | g_return_val_if_fail(status != NULL, NULL); |
1008 | 0 | g_return_val_if_fail(id != NULL, NULL); |
1009 | | |
1010 | 0 | return (PurpleValue *)g_hash_table_lookup(status->attr_values, id); |
1011 | 0 | } |
1012 | | |
1013 | | gboolean |
1014 | | purple_status_get_attr_boolean(const PurpleStatus *status, const char *id) |
1015 | 0 | { |
1016 | 0 | const PurpleValue *value; |
1017 | |
|
1018 | 0 | g_return_val_if_fail(status != NULL, FALSE); |
1019 | 0 | g_return_val_if_fail(id != NULL, FALSE); |
1020 | | |
1021 | 0 | if ((value = purple_status_get_attr_value(status, id)) == NULL) |
1022 | 0 | return FALSE; |
1023 | | |
1024 | 0 | g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN, FALSE); |
1025 | | |
1026 | 0 | return purple_value_get_boolean(value); |
1027 | 0 | } |
1028 | | |
1029 | | int |
1030 | | purple_status_get_attr_int(const PurpleStatus *status, const char *id) |
1031 | 0 | { |
1032 | 0 | const PurpleValue *value; |
1033 | |
|
1034 | 0 | g_return_val_if_fail(status != NULL, 0); |
1035 | 0 | g_return_val_if_fail(id != NULL, 0); |
1036 | | |
1037 | 0 | if ((value = purple_status_get_attr_value(status, id)) == NULL) |
1038 | 0 | return 0; |
1039 | | |
1040 | 0 | g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_INT, 0); |
1041 | | |
1042 | 0 | return purple_value_get_int(value); |
1043 | 0 | } |
1044 | | |
1045 | | const char * |
1046 | | purple_status_get_attr_string(const PurpleStatus *status, const char *id) |
1047 | 0 | { |
1048 | 0 | const PurpleValue *value; |
1049 | |
|
1050 | 0 | g_return_val_if_fail(status != NULL, NULL); |
1051 | 0 | g_return_val_if_fail(id != NULL, NULL); |
1052 | | |
1053 | 0 | if ((value = purple_status_get_attr_value(status, id)) == NULL) |
1054 | 0 | return NULL; |
1055 | | |
1056 | 0 | g_return_val_if_fail(purple_value_get_type(value) == PURPLE_TYPE_STRING, NULL); |
1057 | | |
1058 | 0 | return purple_value_get_string(value); |
1059 | 0 | } |
1060 | | |
1061 | | gint |
1062 | | purple_status_compare(const PurpleStatus *status1, const PurpleStatus *status2) |
1063 | 0 | { |
1064 | 0 | PurpleStatusType *type1, *type2; |
1065 | 0 | int score1 = 0, score2 = 0; |
1066 | |
|
1067 | 0 | if ((status1 == NULL && status2 == NULL) || |
1068 | 0 | (status1 == status2)) |
1069 | 0 | { |
1070 | 0 | return 0; |
1071 | 0 | } |
1072 | 0 | else if (status1 == NULL) |
1073 | 0 | return 1; |
1074 | 0 | else if (status2 == NULL) |
1075 | 0 | return -1; |
1076 | | |
1077 | 0 | type1 = purple_status_get_type(status1); |
1078 | 0 | type2 = purple_status_get_type(status2); |
1079 | |
|
1080 | 0 | if (purple_status_is_active(status1)) |
1081 | 0 | score1 = primitive_scores[purple_status_type_get_primitive(type1)]; |
1082 | |
|
1083 | 0 | if (purple_status_is_active(status2)) |
1084 | 0 | score2 = primitive_scores[purple_status_type_get_primitive(type2)]; |
1085 | |
|
1086 | 0 | if (score1 > score2) |
1087 | 0 | return -1; |
1088 | 0 | else if (score1 < score2) |
1089 | 0 | return 1; |
1090 | | |
1091 | 0 | return 0; |
1092 | 0 | } |
1093 | | |
1094 | | |
1095 | | /************************************************************************** |
1096 | | * PurplePresence API |
1097 | | **************************************************************************/ |
1098 | | PurplePresence * |
1099 | | purple_presence_new(PurplePresenceContext context) |
1100 | 0 | { |
1101 | 0 | PurplePresence *presence; |
1102 | |
|
1103 | 0 | g_return_val_if_fail(context != PURPLE_PRESENCE_CONTEXT_UNSET, NULL); |
1104 | | |
1105 | 0 | presence = g_new0(PurplePresence, 1); |
1106 | 0 | PURPLE_DBUS_REGISTER_POINTER(presence, PurplePresence); |
1107 | |
|
1108 | 0 | presence->context = context; |
1109 | |
|
1110 | 0 | presence->status_table = |
1111 | 0 | g_hash_table_new_full(g_str_hash, g_str_equal, |
1112 | 0 | g_free, NULL); |
1113 | |
|
1114 | 0 | return presence; |
1115 | 0 | } |
1116 | | |
1117 | | PurplePresence * |
1118 | | purple_presence_new_for_account(PurpleAccount *account) |
1119 | 0 | { |
1120 | 0 | PurplePresence *presence = NULL; |
1121 | 0 | g_return_val_if_fail(account != NULL, NULL); |
1122 | | |
1123 | 0 | presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_ACCOUNT); |
1124 | 0 | presence->u.account = account; |
1125 | 0 | presence->statuses = purple_prpl_get_statuses(account, presence); |
1126 | |
|
1127 | 0 | return presence; |
1128 | 0 | } |
1129 | | |
1130 | | PurplePresence * |
1131 | | purple_presence_new_for_conv(PurpleConversation *conv) |
1132 | 0 | { |
1133 | 0 | PurplePresence *presence; |
1134 | |
|
1135 | 0 | g_return_val_if_fail(conv != NULL, NULL); |
1136 | | |
1137 | 0 | presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_CONV); |
1138 | 0 | presence->u.chat.conv = conv; |
1139 | | /* presence->statuses = purple_prpl_get_statuses(conv->account, presence); ? */ |
1140 | |
|
1141 | 0 | return presence; |
1142 | 0 | } |
1143 | | |
1144 | | PurplePresence * |
1145 | | purple_presence_new_for_buddy(PurpleBuddy *buddy) |
1146 | 0 | { |
1147 | 0 | PurplePresence *presence; |
1148 | 0 | PurpleAccount *account; |
1149 | |
|
1150 | 0 | g_return_val_if_fail(buddy != NULL, NULL); |
1151 | 0 | account = purple_buddy_get_account(buddy); |
1152 | |
|
1153 | 0 | presence = purple_presence_new(PURPLE_PRESENCE_CONTEXT_BUDDY); |
1154 | |
|
1155 | 0 | presence->u.buddy.name = g_strdup(purple_buddy_get_name(buddy)); |
1156 | 0 | presence->u.buddy.account = account; |
1157 | 0 | presence->statuses = purple_prpl_get_statuses(account, presence); |
1158 | |
|
1159 | 0 | presence->u.buddy.buddy = buddy; |
1160 | |
|
1161 | 0 | return presence; |
1162 | 0 | } |
1163 | | |
1164 | | void |
1165 | | purple_presence_destroy(PurplePresence *presence) |
1166 | 0 | { |
1167 | 0 | g_return_if_fail(presence != NULL); |
1168 | | |
1169 | 0 | if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_BUDDY) |
1170 | 0 | { |
1171 | 0 | g_free(presence->u.buddy.name); |
1172 | 0 | } |
1173 | 0 | else if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_CONV) |
1174 | 0 | { |
1175 | 0 | g_free(presence->u.chat.user); |
1176 | 0 | } |
1177 | |
|
1178 | 0 | g_list_free_full(presence->statuses, (GDestroyNotify)purple_status_destroy); |
1179 | |
|
1180 | 0 | g_hash_table_destroy(presence->status_table); |
1181 | |
|
1182 | 0 | PURPLE_DBUS_UNREGISTER_POINTER(presence); |
1183 | 0 | g_free(presence); |
1184 | 0 | } |
1185 | | |
1186 | | void |
1187 | | purple_presence_add_status(PurplePresence *presence, PurpleStatus *status) |
1188 | 0 | { |
1189 | 0 | g_return_if_fail(presence != NULL); |
1190 | 0 | g_return_if_fail(status != NULL); |
1191 | | |
1192 | 0 | presence->statuses = g_list_append(presence->statuses, status); |
1193 | |
|
1194 | 0 | g_hash_table_insert(presence->status_table, |
1195 | 0 | g_strdup(purple_status_get_id(status)), status); |
1196 | 0 | } |
1197 | | |
1198 | | void |
1199 | | purple_presence_add_list(PurplePresence *presence, GList *source_list) |
1200 | 0 | { |
1201 | 0 | GList *l; |
1202 | |
|
1203 | 0 | g_return_if_fail(presence != NULL); |
1204 | 0 | g_return_if_fail(source_list != NULL); |
1205 | | |
1206 | 0 | for (l = source_list; l != NULL; l = l->next) |
1207 | 0 | purple_presence_add_status(presence, (PurpleStatus *)l->data); |
1208 | 0 | } |
1209 | | |
1210 | | void |
1211 | | purple_presence_set_status_active(PurplePresence *presence, const char *status_id, |
1212 | | gboolean active) |
1213 | 0 | { |
1214 | 0 | PurpleStatus *status; |
1215 | |
|
1216 | 0 | g_return_if_fail(presence != NULL); |
1217 | 0 | g_return_if_fail(status_id != NULL); |
1218 | | |
1219 | 0 | status = purple_presence_get_status(presence, status_id); |
1220 | |
|
1221 | 0 | g_return_if_fail(status != NULL); |
1222 | | /* TODO: Should we do the following? */ |
1223 | | /* g_return_if_fail(active == status->active); */ |
1224 | | |
1225 | 0 | if (purple_status_is_exclusive(status)) |
1226 | 0 | { |
1227 | 0 | if (!active) |
1228 | 0 | { |
1229 | 0 | purple_debug_warning("status", |
1230 | 0 | "Attempted to set a non-independent status " |
1231 | 0 | "(%s) inactive. Only independent statuses " |
1232 | 0 | "can be specifically marked inactive.", |
1233 | 0 | status_id); |
1234 | 0 | return; |
1235 | 0 | } |
1236 | 0 | } |
1237 | | |
1238 | 0 | purple_status_set_active(status, active); |
1239 | 0 | } |
1240 | | |
1241 | | void |
1242 | | purple_presence_switch_status(PurplePresence *presence, const char *status_id) |
1243 | 0 | { |
1244 | 0 | purple_presence_set_status_active(presence, status_id, TRUE); |
1245 | 0 | } |
1246 | | |
1247 | | static void |
1248 | | update_buddy_idle(PurpleBuddy *buddy, PurplePresence *presence, |
1249 | | time_t current_time, gboolean old_idle, gboolean idle) |
1250 | 0 | { |
1251 | 0 | PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); |
1252 | 0 | PurpleAccount *account = purple_buddy_get_account(buddy); |
1253 | |
|
1254 | 0 | if (!old_idle && idle) |
1255 | 0 | { |
1256 | 0 | if (purple_prefs_get_bool("/purple/logging/log_system")) |
1257 | 0 | { |
1258 | 0 | PurpleLog *log = purple_account_get_log(account, FALSE); |
1259 | |
|
1260 | 0 | if (log != NULL) |
1261 | 0 | { |
1262 | 0 | char *tmp, *tmp2; |
1263 | 0 | tmp = g_strdup_printf(_("%s became idle"), |
1264 | 0 | purple_buddy_get_alias(buddy)); |
1265 | 0 | tmp2 = g_markup_escape_text(tmp, -1); |
1266 | 0 | g_free(tmp); |
1267 | |
|
1268 | 0 | purple_log_write(log, PURPLE_MESSAGE_SYSTEM, |
1269 | 0 | purple_buddy_get_alias(buddy), current_time, tmp2); |
1270 | 0 | g_free(tmp2); |
1271 | 0 | } |
1272 | 0 | } |
1273 | 0 | } |
1274 | 0 | else if (old_idle && !idle) |
1275 | 0 | { |
1276 | 0 | if (purple_prefs_get_bool("/purple/logging/log_system")) |
1277 | 0 | { |
1278 | 0 | PurpleLog *log = purple_account_get_log(account, FALSE); |
1279 | |
|
1280 | 0 | if (log != NULL) |
1281 | 0 | { |
1282 | 0 | char *tmp, *tmp2; |
1283 | 0 | tmp = g_strdup_printf(_("%s became unidle"), |
1284 | 0 | purple_buddy_get_alias(buddy)); |
1285 | 0 | tmp2 = g_markup_escape_text(tmp, -1); |
1286 | 0 | g_free(tmp); |
1287 | |
|
1288 | 0 | purple_log_write(log, PURPLE_MESSAGE_SYSTEM, |
1289 | 0 | purple_buddy_get_alias(buddy), current_time, tmp2); |
1290 | 0 | g_free(tmp2); |
1291 | 0 | } |
1292 | 0 | } |
1293 | 0 | } |
1294 | |
|
1295 | 0 | if (old_idle != idle) |
1296 | 0 | purple_signal_emit(purple_blist_get_handle(), "buddy-idle-changed", buddy, |
1297 | 0 | old_idle, idle); |
1298 | |
|
1299 | 0 | purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy)); |
1300 | | |
1301 | | /* Should this be done here? It'd perhaps make more sense to |
1302 | | * connect to buddy-[un]idle signals and update from there |
1303 | | */ |
1304 | |
|
1305 | 0 | if (ops != NULL && ops->update != NULL) |
1306 | 0 | ops->update(purple_get_blist(), (PurpleBlistNode *)buddy); |
1307 | 0 | } |
1308 | | |
1309 | | void |
1310 | | purple_presence_set_idle(PurplePresence *presence, gboolean idle, time_t idle_time) |
1311 | 0 | { |
1312 | 0 | gboolean old_idle; |
1313 | 0 | time_t current_time; |
1314 | |
|
1315 | 0 | g_return_if_fail(presence != NULL); |
1316 | | |
1317 | 0 | if (presence->idle == idle && presence->idle_time == idle_time) |
1318 | 0 | return; |
1319 | | |
1320 | 0 | old_idle = presence->idle; |
1321 | 0 | presence->idle = idle; |
1322 | 0 | presence->idle_time = (idle ? idle_time : 0); |
1323 | |
|
1324 | 0 | current_time = time(NULL); |
1325 | |
|
1326 | 0 | if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_BUDDY) |
1327 | 0 | { |
1328 | 0 | update_buddy_idle(purple_presence_get_buddy(presence), presence, current_time, |
1329 | 0 | old_idle, idle); |
1330 | 0 | } |
1331 | 0 | else if (purple_presence_get_context(presence) == PURPLE_PRESENCE_CONTEXT_ACCOUNT) |
1332 | 0 | { |
1333 | 0 | PurpleAccount *account; |
1334 | 0 | PurpleConnection *gc = NULL; |
1335 | 0 | PurplePlugin *prpl = NULL; |
1336 | 0 | PurplePluginProtocolInfo *prpl_info = NULL; |
1337 | |
|
1338 | 0 | account = purple_presence_get_account(presence); |
1339 | |
|
1340 | 0 | if (purple_prefs_get_bool("/purple/logging/log_system")) |
1341 | 0 | { |
1342 | 0 | PurpleLog *log = purple_account_get_log(account, FALSE); |
1343 | |
|
1344 | 0 | if (log != NULL) |
1345 | 0 | { |
1346 | 0 | char *msg, *tmp; |
1347 | |
|
1348 | 0 | if (idle) |
1349 | 0 | tmp = g_strdup_printf(_("+++ %s became idle"), purple_account_get_username(account)); |
1350 | 0 | else |
1351 | 0 | tmp = g_strdup_printf(_("+++ %s became unidle"), purple_account_get_username(account)); |
1352 | |
|
1353 | 0 | msg = g_markup_escape_text(tmp, -1); |
1354 | 0 | g_free(tmp); |
1355 | 0 | purple_log_write(log, PURPLE_MESSAGE_SYSTEM, |
1356 | 0 | purple_account_get_username(account), |
1357 | 0 | (idle ? idle_time : current_time), msg); |
1358 | 0 | g_free(msg); |
1359 | 0 | } |
1360 | 0 | } |
1361 | |
|
1362 | 0 | gc = purple_account_get_connection(account); |
1363 | |
|
1364 | 0 | if(gc) |
1365 | 0 | prpl = purple_connection_get_prpl(gc); |
1366 | |
|
1367 | 0 | if(PURPLE_CONNECTION_IS_CONNECTED(gc) && prpl != NULL) |
1368 | 0 | prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
1369 | |
|
1370 | 0 | if (prpl_info && prpl_info->set_idle) |
1371 | 0 | prpl_info->set_idle(gc, (idle ? (current_time - idle_time) : 0)); |
1372 | 0 | } |
1373 | 0 | } |
1374 | | |
1375 | | void |
1376 | | purple_presence_set_login_time(PurplePresence *presence, time_t login_time) |
1377 | 0 | { |
1378 | 0 | g_return_if_fail(presence != NULL); |
1379 | | |
1380 | 0 | if (presence->login_time == login_time) |
1381 | 0 | return; |
1382 | | |
1383 | 0 | presence->login_time = login_time; |
1384 | 0 | } |
1385 | | |
1386 | | PurplePresenceContext |
1387 | | purple_presence_get_context(const PurplePresence *presence) |
1388 | 0 | { |
1389 | 0 | g_return_val_if_fail(presence != NULL, PURPLE_PRESENCE_CONTEXT_UNSET); |
1390 | | |
1391 | 0 | return presence->context; |
1392 | 0 | } |
1393 | | |
1394 | | PurpleAccount * |
1395 | | purple_presence_get_account(const PurplePresence *presence) |
1396 | 0 | { |
1397 | 0 | PurplePresenceContext context; |
1398 | |
|
1399 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1400 | | |
1401 | 0 | context = purple_presence_get_context(presence); |
1402 | |
|
1403 | 0 | g_return_val_if_fail(context == PURPLE_PRESENCE_CONTEXT_ACCOUNT || |
1404 | 0 | context == PURPLE_PRESENCE_CONTEXT_BUDDY, NULL); |
1405 | | |
1406 | 0 | return presence->u.account; |
1407 | 0 | } |
1408 | | |
1409 | | PurpleConversation * |
1410 | | purple_presence_get_conversation(const PurplePresence *presence) |
1411 | 0 | { |
1412 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1413 | 0 | g_return_val_if_fail(purple_presence_get_context(presence) == |
1414 | 0 | PURPLE_PRESENCE_CONTEXT_CONV, NULL); |
1415 | | |
1416 | 0 | return presence->u.chat.conv; |
1417 | 0 | } |
1418 | | |
1419 | | const char * |
1420 | | purple_presence_get_chat_user(const PurplePresence *presence) |
1421 | 0 | { |
1422 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1423 | 0 | g_return_val_if_fail(purple_presence_get_context(presence) == |
1424 | 0 | PURPLE_PRESENCE_CONTEXT_CONV, NULL); |
1425 | | |
1426 | 0 | return presence->u.chat.user; |
1427 | 0 | } |
1428 | | |
1429 | | PurpleBuddy * |
1430 | | purple_presence_get_buddy(const PurplePresence *presence) |
1431 | 0 | { |
1432 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1433 | 0 | g_return_val_if_fail(purple_presence_get_context(presence) == |
1434 | 0 | PURPLE_PRESENCE_CONTEXT_BUDDY, NULL); |
1435 | | |
1436 | 0 | return presence->u.buddy.buddy; |
1437 | 0 | } |
1438 | | |
1439 | | GList * |
1440 | | purple_presence_get_statuses(const PurplePresence *presence) |
1441 | 0 | { |
1442 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1443 | | |
1444 | 0 | return presence->statuses; |
1445 | 0 | } |
1446 | | |
1447 | | PurpleStatus * |
1448 | | purple_presence_get_status(const PurplePresence *presence, const char *status_id) |
1449 | 0 | { |
1450 | 0 | PurpleStatus *status; |
1451 | 0 | GList *l = NULL; |
1452 | |
|
1453 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1454 | 0 | g_return_val_if_fail(status_id != NULL, NULL); |
1455 | | |
1456 | | /* What's the purpose of this hash table? */ |
1457 | 0 | status = (PurpleStatus *)g_hash_table_lookup(presence->status_table, |
1458 | 0 | status_id); |
1459 | |
|
1460 | 0 | if (status == NULL) { |
1461 | 0 | for (l = purple_presence_get_statuses(presence); |
1462 | 0 | l != NULL && status == NULL; l = l->next) |
1463 | 0 | { |
1464 | 0 | PurpleStatus *temp_status = l->data; |
1465 | |
|
1466 | 0 | if (purple_strequal(status_id, purple_status_get_id(temp_status))) |
1467 | 0 | status = temp_status; |
1468 | 0 | } |
1469 | |
|
1470 | 0 | if (status != NULL) |
1471 | 0 | g_hash_table_insert(presence->status_table, |
1472 | 0 | g_strdup(purple_status_get_id(status)), status); |
1473 | 0 | } |
1474 | |
|
1475 | 0 | return status; |
1476 | 0 | } |
1477 | | |
1478 | | PurpleStatus * |
1479 | | purple_presence_get_active_status(const PurplePresence *presence) |
1480 | 0 | { |
1481 | 0 | g_return_val_if_fail(presence != NULL, NULL); |
1482 | | |
1483 | 0 | return presence->active_status; |
1484 | 0 | } |
1485 | | |
1486 | | gboolean |
1487 | | purple_presence_is_available(const PurplePresence *presence) |
1488 | 0 | { |
1489 | 0 | PurpleStatus *status; |
1490 | |
|
1491 | 0 | g_return_val_if_fail(presence != NULL, FALSE); |
1492 | | |
1493 | 0 | status = purple_presence_get_active_status(presence); |
1494 | |
|
1495 | 0 | return ((status != NULL && purple_status_is_available(status)) && |
1496 | 0 | !purple_presence_is_idle(presence)); |
1497 | 0 | } |
1498 | | |
1499 | | gboolean |
1500 | | purple_presence_is_online(const PurplePresence *presence) |
1501 | 0 | { |
1502 | 0 | PurpleStatus *status; |
1503 | |
|
1504 | 0 | g_return_val_if_fail(presence != NULL, FALSE); |
1505 | | |
1506 | 0 | if ((status = purple_presence_get_active_status(presence)) == NULL) |
1507 | 0 | return FALSE; |
1508 | | |
1509 | 0 | return purple_status_is_online(status); |
1510 | 0 | } |
1511 | | |
1512 | | gboolean |
1513 | | purple_presence_is_status_active(const PurplePresence *presence, |
1514 | | const char *status_id) |
1515 | 0 | { |
1516 | 0 | PurpleStatus *status; |
1517 | |
|
1518 | 0 | g_return_val_if_fail(presence != NULL, FALSE); |
1519 | 0 | g_return_val_if_fail(status_id != NULL, FALSE); |
1520 | | |
1521 | 0 | status = purple_presence_get_status(presence, status_id); |
1522 | |
|
1523 | 0 | return (status != NULL && purple_status_is_active(status)); |
1524 | 0 | } |
1525 | | |
1526 | | gboolean |
1527 | | purple_presence_is_status_primitive_active(const PurplePresence *presence, |
1528 | | PurpleStatusPrimitive primitive) |
1529 | 0 | { |
1530 | 0 | GList *l; |
1531 | |
|
1532 | 0 | g_return_val_if_fail(presence != NULL, FALSE); |
1533 | 0 | g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, FALSE); |
1534 | | |
1535 | 0 | for (l = purple_presence_get_statuses(presence); |
1536 | 0 | l != NULL; l = l->next) |
1537 | 0 | { |
1538 | 0 | PurpleStatus *temp_status = l->data; |
1539 | 0 | PurpleStatusType *type = purple_status_get_type(temp_status); |
1540 | |
|
1541 | 0 | if (purple_status_type_get_primitive(type) == primitive && |
1542 | 0 | purple_status_is_active(temp_status)) |
1543 | 0 | return TRUE; |
1544 | 0 | } |
1545 | 0 | return FALSE; |
1546 | 0 | } |
1547 | | |
1548 | | gboolean |
1549 | | purple_presence_is_idle(const PurplePresence *presence) |
1550 | 0 | { |
1551 | 0 | g_return_val_if_fail(presence != NULL, FALSE); |
1552 | | |
1553 | 0 | return purple_presence_is_online(presence) && presence->idle; |
1554 | 0 | } |
1555 | | |
1556 | | time_t |
1557 | | purple_presence_get_idle_time(const PurplePresence *presence) |
1558 | 0 | { |
1559 | 0 | g_return_val_if_fail(presence != NULL, 0); |
1560 | | |
1561 | 0 | return presence->idle_time; |
1562 | 0 | } |
1563 | | |
1564 | | time_t |
1565 | | purple_presence_get_login_time(const PurplePresence *presence) |
1566 | 0 | { |
1567 | 0 | g_return_val_if_fail(presence != NULL, 0); |
1568 | | |
1569 | 0 | return purple_presence_is_online(presence) ? presence->login_time : 0; |
1570 | 0 | } |
1571 | | |
1572 | | static int |
1573 | | purple_presence_compute_score(const PurplePresence *presence) |
1574 | 0 | { |
1575 | 0 | GList *l; |
1576 | 0 | int score = 0; |
1577 | |
|
1578 | 0 | for (l = purple_presence_get_statuses(presence); l != NULL; l = l->next) { |
1579 | 0 | PurpleStatus *status = (PurpleStatus *)l->data; |
1580 | 0 | PurpleStatusType *type = purple_status_get_type(status); |
1581 | |
|
1582 | 0 | if (purple_status_is_active(status)) { |
1583 | 0 | score += primitive_scores[purple_status_type_get_primitive(type)]; |
1584 | 0 | if (!purple_status_is_online(status)) { |
1585 | 0 | PurpleBuddy *b = purple_presence_get_buddy(presence); |
1586 | 0 | if (b && purple_account_supports_offline_message(purple_buddy_get_account(b), b)) |
1587 | 0 | score += primitive_scores[SCORE_OFFLINE_MESSAGE]; |
1588 | 0 | } |
1589 | 0 | } |
1590 | 0 | } |
1591 | 0 | score += purple_account_get_int(purple_presence_get_account(presence), "score", 0); |
1592 | 0 | if (purple_presence_is_idle(presence)) |
1593 | 0 | score += primitive_scores[SCORE_IDLE]; |
1594 | 0 | return score; |
1595 | 0 | } |
1596 | | |
1597 | | gint |
1598 | | purple_presence_compare(const PurplePresence *presence1, |
1599 | | const PurplePresence *presence2) |
1600 | 0 | { |
1601 | 0 | time_t idle_time_1, idle_time_2; |
1602 | 0 | int score1 = 0, score2 = 0; |
1603 | |
|
1604 | 0 | if (presence1 == presence2) |
1605 | 0 | return 0; |
1606 | 0 | else if (presence1 == NULL) |
1607 | 0 | return 1; |
1608 | 0 | else if (presence2 == NULL) |
1609 | 0 | return -1; |
1610 | | |
1611 | 0 | if (purple_presence_is_online(presence1) && |
1612 | 0 | !purple_presence_is_online(presence2)) |
1613 | 0 | return -1; |
1614 | 0 | else if (purple_presence_is_online(presence2) && |
1615 | 0 | !purple_presence_is_online(presence1)) |
1616 | 0 | return 1; |
1617 | | |
1618 | | /* Compute the score of the first set of statuses. */ |
1619 | 0 | score1 = purple_presence_compute_score(presence1); |
1620 | | |
1621 | | /* Compute the score of the second set of statuses. */ |
1622 | 0 | score2 = purple_presence_compute_score(presence2); |
1623 | |
|
1624 | 0 | idle_time_1 = time(NULL) - purple_presence_get_idle_time(presence1); |
1625 | 0 | idle_time_2 = time(NULL) - purple_presence_get_idle_time(presence2); |
1626 | |
|
1627 | 0 | if (idle_time_1 > idle_time_2) |
1628 | 0 | score1 += primitive_scores[SCORE_IDLE_TIME]; |
1629 | 0 | else if (idle_time_1 < idle_time_2) |
1630 | 0 | score2 += primitive_scores[SCORE_IDLE_TIME]; |
1631 | |
|
1632 | 0 | if (score1 < score2) |
1633 | 0 | return 1; |
1634 | 0 | else if (score1 > score2) |
1635 | 0 | return -1; |
1636 | | |
1637 | 0 | return 0; |
1638 | 0 | } |
1639 | | |
1640 | | |
1641 | | /************************************************************************** |
1642 | | * Status subsystem |
1643 | | **************************************************************************/ |
1644 | | static void |
1645 | | score_pref_changed_cb(const char *name, PurplePrefType type, |
1646 | | gconstpointer value, gpointer data) |
1647 | 0 | { |
1648 | 0 | int index = GPOINTER_TO_INT(data); |
1649 | |
|
1650 | 0 | primitive_scores[index] = GPOINTER_TO_INT(value); |
1651 | 0 | } |
1652 | | |
1653 | | void * |
1654 | 0 | purple_status_get_handle(void) { |
1655 | 0 | static int handle; |
1656 | |
|
1657 | 0 | return &handle; |
1658 | 0 | } |
1659 | | |
1660 | | void |
1661 | | purple_status_init(void) |
1662 | 0 | { |
1663 | 0 | void *handle = purple_status_get_handle(); |
1664 | |
|
1665 | 0 | purple_prefs_add_none("/purple/status"); |
1666 | 0 | purple_prefs_add_none("/purple/status/scores"); |
1667 | |
|
1668 | 0 | purple_prefs_add_int("/purple/status/scores/offline", |
1669 | 0 | primitive_scores[PURPLE_STATUS_OFFLINE]); |
1670 | 0 | purple_prefs_add_int("/purple/status/scores/available", |
1671 | 0 | primitive_scores[PURPLE_STATUS_AVAILABLE]); |
1672 | 0 | purple_prefs_add_int("/purple/status/scores/invisible", |
1673 | 0 | primitive_scores[PURPLE_STATUS_INVISIBLE]); |
1674 | 0 | purple_prefs_add_int("/purple/status/scores/away", |
1675 | 0 | primitive_scores[PURPLE_STATUS_AWAY]); |
1676 | 0 | purple_prefs_add_int("/purple/status/scores/extended_away", |
1677 | 0 | primitive_scores[PURPLE_STATUS_EXTENDED_AWAY]); |
1678 | 0 | purple_prefs_add_int("/purple/status/scores/idle", |
1679 | 0 | primitive_scores[SCORE_IDLE]); |
1680 | 0 | purple_prefs_add_int("/purple/status/scores/offline_msg", |
1681 | 0 | primitive_scores[SCORE_OFFLINE_MESSAGE]); |
1682 | |
|
1683 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/offline", |
1684 | 0 | score_pref_changed_cb, |
1685 | 0 | GINT_TO_POINTER(PURPLE_STATUS_OFFLINE)); |
1686 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/available", |
1687 | 0 | score_pref_changed_cb, |
1688 | 0 | GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE)); |
1689 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/invisible", |
1690 | 0 | score_pref_changed_cb, |
1691 | 0 | GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE)); |
1692 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/away", |
1693 | 0 | score_pref_changed_cb, |
1694 | 0 | GINT_TO_POINTER(PURPLE_STATUS_AWAY)); |
1695 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/extended_away", |
1696 | 0 | score_pref_changed_cb, |
1697 | 0 | GINT_TO_POINTER(PURPLE_STATUS_EXTENDED_AWAY)); |
1698 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/idle", |
1699 | 0 | score_pref_changed_cb, |
1700 | 0 | GINT_TO_POINTER(SCORE_IDLE)); |
1701 | 0 | purple_prefs_connect_callback(handle, "/purple/status/scores/offline_msg", |
1702 | 0 | score_pref_changed_cb, |
1703 | 0 | GINT_TO_POINTER(SCORE_OFFLINE_MESSAGE)); |
1704 | |
|
1705 | 0 | purple_prefs_trigger_callback("/purple/status/scores/offline"); |
1706 | 0 | purple_prefs_trigger_callback("/purple/status/scores/available"); |
1707 | 0 | purple_prefs_trigger_callback("/purple/status/scores/invisible"); |
1708 | 0 | purple_prefs_trigger_callback("/purple/status/scores/away"); |
1709 | 0 | purple_prefs_trigger_callback("/purple/status/scores/extended_away"); |
1710 | 0 | purple_prefs_trigger_callback("/purple/status/scores/idle"); |
1711 | 0 | purple_prefs_trigger_callback("/purple/status/scores/offline_msg"); |
1712 | 0 | } |
1713 | | |
1714 | | void |
1715 | | purple_status_uninit(void) |
1716 | 0 | { |
1717 | 0 | purple_prefs_disconnect_by_handle(purple_prefs_get_handle()); |
1718 | 0 | } |