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