Mercurial > pidgin.yaz
annotate src/status.c @ 12595:3169cd6727ad
[gaim-migrate @ 14925]
I've been meaning to spend the time to commit these changes separately, but it's been a couple days without me finding the time...
1. Allow the creation of GaimStatusTypes by passing NULL for the name and/or id. The core uses the default name and/or id. This eliminates quite a bit of duplication in the prpls.
2. Make statuses more consistent. For example, in some prpls, "Busy" was descended from the UNAVAILABLE primitive and on others it was a case of AWAY. Another example... "On Vacation" is definitely an EXTENDED_AWAY not an AWAY.
3. Rename some pixmaps to elminate some special cases. The names of the pixmaps should now match the primitive default IDs.
4. Rename the HIDDEN primitive to INVISIBLE, since we seem to be using that term everywhere. In conjunction with #1, more duplication was eliminated.
5. Add a MOBILE status primitive. It's not used now. It'll be needed in the (hopefully not-too-distant) future, so I'm planning ahead.
6. Shrink the status select for small blist folks. Now if someone can get rid of that stupid extra padding, we'll be set (well, after we deal with imhtml space issues). I've fought with this for many many hours over several days and I can't get it. It's clear that the combo box is requesting more space than is really necessary, but I don't know why.
This is really my first go at anything significant status-related. Everyone should check their favorite prpls carefully to make sure I didn't break anything.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Wed, 21 Dec 2005 08:24:17 +0000 |
parents | 8afd25a37b35 |
children | 57462d6542ea |
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 | |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
139 #define SCORE_IDLE 7 |
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
140 #define SCORE_IDLE_TIME 8 |
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 | |
11624 | 619 if (((old_status == NULL) || !gaim_status_is_available(old_status)) && |
9949 | 620 gaim_status_is_available(new_status)) |
621 { | |
622 tmp = g_strdup_printf(_("%s came back"), buddy_alias); | |
623 } | |
11624 | 624 else if ((old_status != NULL) && gaim_status_is_available(old_status) && |
9949 | 625 !gaim_status_is_available(new_status)) |
626 { | |
627 tmp = g_strdup_printf(_("%s went away"), buddy_alias); | |
628 } | |
629 | |
630 if (tmp != NULL) | |
631 { | |
632 GaimLog *log = gaim_account_get_log(buddy->account); | |
633 | |
634 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, | |
635 current_time, tmp); | |
636 g_free(tmp); | |
637 } | |
638 } | |
639 | |
10012 | 640 if (ops != NULL && ops->update != NULL) |
641 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 642 } |
643 | |
644 static void | |
645 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
646 GaimStatus *new_status) |
6065 | 647 { |
9949 | 648 GaimPresenceContext context = gaim_presence_get_context(presence); |
649 | |
650 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) | |
651 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
652 GaimAccount *account = gaim_presence_get_account(presence); |
9949 | 653 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); |
654 | |
10400 | 655 if (gaim_account_get_enabled(account, gaim_core_get_ui())) |
10447 | 656 gaim_prpl_change_account_status(account, old_status, new_status); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
657 |
9949 | 658 if (ops != NULL && ops->status_changed != NULL) |
659 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
660 ops->status_changed(account, new_status); |
9949 | 661 } |
662 } | |
663 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
664 { | |
665 const GList *l; | |
666 | |
667 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
668 { | |
669 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
670 old_status, new_status); | |
671 } | |
672 } | |
673 } | |
674 | |
10204 | 675 static void |
676 status_has_changed(GaimStatus *status) | |
9949 | 677 { |
678 GaimPresence *presence; | |
679 GaimStatus *old_status; | |
680 | |
681 presence = gaim_status_get_presence(status); | |
682 | |
10204 | 683 /* |
684 * If this status is exclusive, then we must be setting it to "active." | |
685 * Since we are setting it to active, we want to set the currently | |
686 * active status to "inactive." | |
687 */ | |
688 if (gaim_status_is_exclusive(status)) | |
9949 | 689 { |
10754 | 690 old_status = gaim_presence_get_active_status(presence); |
10760 | 691 if (old_status != NULL && (old_status != status)) |
10754 | 692 old_status->active = FALSE; |
693 presence->active_status = status; | |
9949 | 694 } |
10754 | 695 else |
696 old_status = NULL; | |
9949 | 697 |
10204 | 698 notify_status_update(presence, old_status, status); |
699 } | |
700 | |
701 void | |
702 gaim_status_set_active(GaimStatus *status, gboolean active) | |
703 { | |
10754 | 704 gaim_status_set_active_with_attrs(status, active, NULL); |
10204 | 705 } |
706 | |
11249 | 707 /* |
708 * This used to parse the va_list directly, but now it creates a GList | |
709 * and passes it to gaim_status_set_active_with_attrs_list(). That | |
710 * function was created because accounts.c needs to pass a GList of | |
711 * attributes to the status API. | |
712 */ | |
10204 | 713 void |
714 gaim_status_set_active_with_attrs(GaimStatus *status, gboolean active, va_list args) | |
715 { | |
11249 | 716 GList *attrs = NULL; |
717 const gchar *id; | |
718 gpointer data; | |
719 | |
720 if (args != NULL) | |
721 { | |
722 while ((id = va_arg(args, const char *)) != NULL) | |
723 { | |
724 attrs = g_list_append(attrs, (char *)id); | |
725 data = va_arg(args, void *); | |
726 attrs = g_list_append(attrs, data); | |
727 } | |
728 } | |
729 gaim_status_set_active_with_attrs_list(status, active, attrs); | |
730 g_list_free(attrs); | |
731 } | |
732 | |
733 void | |
734 gaim_status_set_active_with_attrs_list(GaimStatus *status, gboolean active, | |
735 const GList *attrs) | |
736 { | |
10204 | 737 gboolean changed = FALSE; |
738 const gchar *id; | |
739 | |
10714 | 740 g_return_if_fail(status != NULL); |
741 | |
10204 | 742 if (!active && gaim_status_is_exclusive(status)) |
743 { | |
744 gaim_debug_error("status", | |
745 "Cannot deactivate an exclusive status (%s).\n", | |
746 gaim_status_get_id(status)); | |
747 return; | |
748 } | |
749 | |
750 if (status->active != active) | |
10738 | 751 { |
10204 | 752 changed = TRUE; |
10738 | 753 } |
10204 | 754 |
9949 | 755 status->active = active; |
6065 | 756 |
10204 | 757 /* Set any attributes */ |
11249 | 758 while (attrs) |
10204 | 759 { |
760 GaimValue *value; | |
11249 | 761 |
762 id = attrs->data; | |
763 attrs = attrs->next; | |
10204 | 764 value = gaim_status_get_attr_value(status, id); |
10713 | 765 if (value == NULL) |
766 { | |
767 gaim_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
10714 | 768 "not supported.\n", id, status->type->name); |
10713 | 769 /* Skip over the data and move on to the next attribute */ |
11249 | 770 attrs = attrs->next; |
10713 | 771 continue; |
772 } | |
773 | |
10204 | 774 if (value->type == GAIM_TYPE_STRING) |
775 { | |
11249 | 776 const gchar *string_data = attrs->data; |
777 attrs = attrs->next; | |
10204 | 778 if (((string_data == NULL) && (value->data.string_data == NULL)) || |
779 ((string_data != NULL) && (value->data.string_data != NULL) && | |
780 !strcmp(string_data, value->data.string_data))) | |
781 { | |
782 continue; | |
783 } | |
784 gaim_status_set_attr_string(status, id, string_data); | |
785 changed = TRUE; | |
786 } | |
787 else if (value->type == GAIM_TYPE_INT) | |
788 { | |
11586 | 789 int int_data = GPOINTER_TO_INT(attrs->data); |
11249 | 790 attrs = attrs->next; |
10204 | 791 if (int_data == value->data.int_data) |
792 continue; | |
793 gaim_status_set_attr_int(status, id, int_data); | |
794 changed = TRUE; | |
795 } | |
796 else if (value->type == GAIM_TYPE_BOOLEAN) | |
797 { | |
11586 | 798 gboolean boolean_data = GPOINTER_TO_INT(attrs->data); |
11249 | 799 attrs = attrs->next; |
10204 | 800 if (boolean_data == value->data.boolean_data) |
801 continue; | |
802 gaim_status_set_attr_int(status, id, boolean_data); | |
803 changed = TRUE; | |
804 } | |
805 else | |
806 { | |
807 /* We don't know what the data is--skip over it */ | |
11249 | 808 attrs = attrs->next; |
10204 | 809 } |
810 } | |
811 | |
812 if (!changed) | |
813 return; | |
814 status_has_changed(status); | |
9949 | 815 } |
816 | |
817 void | |
818 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
819 gboolean value) | |
820 { | |
821 GaimStatusType *status_type; | |
822 GaimValue *attr_value; | |
823 | |
824 g_return_if_fail(status != NULL); | |
825 g_return_if_fail(id != NULL); | |
826 | |
827 status_type = gaim_status_get_type(status); | |
828 | |
10197 | 829 /* Make sure this attribute exists and is the correct type. */ |
830 attr_value = gaim_status_get_attr_value(status, id); | |
831 g_return_if_fail(attr_value != NULL); | |
9949 | 832 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); |
833 | |
834 gaim_value_set_boolean(attr_value, value); | |
835 } | |
836 | |
837 void | |
838 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
839 { | |
840 GaimStatusType *status_type; | |
841 GaimValue *attr_value; | |
842 | |
843 g_return_if_fail(status != NULL); | |
844 g_return_if_fail(id != NULL); | |
845 | |
846 status_type = gaim_status_get_type(status); | |
847 | |
10197 | 848 /* Make sure this attribute exists and is the correct type. */ |
849 attr_value = gaim_status_get_attr_value(status, id); | |
850 g_return_if_fail(attr_value != NULL); | |
9949 | 851 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); |
852 | |
853 gaim_value_set_int(attr_value, value); | |
6065 | 854 } |
855 | |
9949 | 856 void |
857 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
858 const char *value) | |
859 { | |
860 GaimStatusType *status_type; | |
861 GaimValue *attr_value; | |
862 | |
863 g_return_if_fail(status != NULL); | |
864 g_return_if_fail(id != NULL); | |
865 | |
866 status_type = gaim_status_get_type(status); | |
867 | |
10197 | 868 /* Make sure this attribute exists and is the correct type. */ |
10196 | 869 attr_value = gaim_status_get_attr_value(status, id); |
12434 | 870 /* This used to be g_return_if_fail, but it's failing a LOT, so |
871 * let's generate a log error for now. */ | |
872 /* g_return_if_fail(attr_value != NULL); */ | |
873 if (attr_value == NULL) { | |
874 gaim_debug_error("status", | |
875 "Attempted to set status attribute '%s' for " | |
876 "status '%s', which is not legal. Fix " | |
877 "this!\n", id, | |
878 gaim_status_type_get_name(gaim_status_get_type(status))); | |
879 return; | |
880 | |
881 } | |
9949 | 882 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); |
883 | |
884 gaim_value_set_string(attr_value, value); | |
885 } | |
886 | |
887 GaimStatusType * | |
888 gaim_status_get_type(const GaimStatus *status) | |
889 { | |
890 g_return_val_if_fail(status != NULL, NULL); | |
891 | |
892 return status->type; | |
893 } | |
894 | |
895 GaimPresence * | |
896 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 897 { |
9949 | 898 g_return_val_if_fail(status != NULL, NULL); |
899 | |
900 return status->presence; | |
901 } | |
902 | |
903 const char * | |
904 gaim_status_get_id(const GaimStatus *status) | |
905 { | |
906 g_return_val_if_fail(status != NULL, NULL); | |
907 | |
908 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
909 } | |
910 | |
911 const char * | |
912 gaim_status_get_name(const GaimStatus *status) | |
913 { | |
914 g_return_val_if_fail(status != NULL, NULL); | |
915 | |
916 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
917 } | |
918 | |
919 gboolean | |
920 gaim_status_is_independent(const GaimStatus *status) | |
921 { | |
922 g_return_val_if_fail(status != NULL, FALSE); | |
923 | |
924 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
925 } | |
926 | |
927 gboolean | |
10067 | 928 gaim_status_is_exclusive(const GaimStatus *status) |
929 { | |
930 g_return_val_if_fail(status != NULL, FALSE); | |
931 | |
932 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
933 } | |
934 | |
935 gboolean | |
9949 | 936 gaim_status_is_available(const GaimStatus *status) |
937 { | |
938 g_return_val_if_fail(status != NULL, FALSE); | |
939 | |
940 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
941 } | |
6216 | 942 |
9949 | 943 gboolean |
944 gaim_status_is_active(const GaimStatus *status) | |
945 { | |
946 g_return_val_if_fail(status != NULL, FALSE); | |
947 | |
948 return status->active; | |
949 } | |
950 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
951 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
952 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
953 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
954 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
955 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
956 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
957 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
958 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
959 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
960 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
961 primitive != GAIM_STATUS_OFFLINE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
962 } |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
963 |
9949 | 964 GaimValue * |
965 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
966 { | |
967 g_return_val_if_fail(status != NULL, NULL); | |
968 g_return_val_if_fail(id != NULL, NULL); | |
969 | |
970 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
971 } | |
972 | |
973 gboolean | |
974 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
975 { | |
976 const GaimValue *value; | |
977 | |
978 g_return_val_if_fail(status != NULL, FALSE); | |
979 g_return_val_if_fail(id != NULL, FALSE); | |
980 | |
981 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
982 return FALSE; | |
983 | |
10197 | 984 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_BOOLEAN, FALSE); |
9949 | 985 |
986 return gaim_value_get_boolean(value); | |
987 } | |
988 | |
989 int | |
990 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
991 { | |
992 const GaimValue *value; | |
993 | |
10507 | 994 g_return_val_if_fail(status != NULL, 0); |
995 g_return_val_if_fail(id != NULL, 0); | |
9949 | 996 |
997 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10507 | 998 return 0; |
9949 | 999 |
1000 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
1001 | |
1002 return gaim_value_get_int(value); | |
1003 } | |
1004 | |
1005 const char * | |
1006 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
1007 { | |
1008 const GaimValue *value; | |
1009 | |
10507 | 1010 g_return_val_if_fail(status != NULL, NULL); |
1011 g_return_val_if_fail(id != NULL, NULL); | |
9949 | 1012 |
1013 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10504 | 1014 return NULL; |
9949 | 1015 |
1016 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
1017 | |
1018 return gaim_value_get_string(value); | |
1019 } | |
1020 | |
1021 gint | |
1022 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
1023 { | |
1024 GaimStatusType *type1, *type2; | |
1025 int score1 = 0, score2 = 0; | |
6065 | 1026 |
9949 | 1027 if ((status1 == NULL && status2 == NULL) || |
1028 (status1 == status2)) | |
1029 { | |
1030 return 0; | |
1031 } | |
1032 else if (status1 == NULL) | |
1033 return 1; | |
1034 else if (status2 == NULL) | |
1035 return -1; | |
1036 | |
1037 type1 = gaim_status_get_type(status1); | |
1038 type2 = gaim_status_get_type(status2); | |
1039 | |
1040 if (gaim_status_is_active(status1)) | |
1041 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
1042 | |
1043 if (gaim_status_is_active(status2)) | |
1044 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
1045 | |
1046 if (score1 > score2) | |
1047 return -1; | |
1048 else if (score1 < score2) | |
1049 return 1; | |
1050 | |
1051 return 0; | |
1052 } | |
1053 | |
1054 | |
1055 /************************************************************************** | |
1056 * GaimPresence API | |
1057 **************************************************************************/ | |
1058 GaimPresence * | |
1059 gaim_presence_new(GaimPresenceContext context) | |
1060 { | |
1061 GaimPresence *presence; | |
1062 | |
1063 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
1064 | |
1065 presence = g_new0(GaimPresence, 1); | |
11187 | 1066 GAIM_DBUS_REGISTER_POINTER(presence, GaimPresence); |
9949 | 1067 |
1068 presence->context = context; | |
1069 | |
1070 presence->status_table = | |
10009 | 1071 g_hash_table_new_full(g_str_hash, g_str_equal, |
11638 | 1072 g_free, NULL); |
9949 | 1073 |
1074 return presence; | |
1075 } | |
1076 | |
1077 GaimPresence * | |
1078 gaim_presence_new_for_account(GaimAccount *account) | |
1079 { | |
10012 | 1080 GaimPresence *presence = NULL; |
9949 | 1081 g_return_val_if_fail(account != NULL, NULL); |
1082 | |
1083 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
1084 presence->u.account = account; | |
10006 | 1085 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 1086 |
1087 return presence; | |
1088 } | |
1089 | |
1090 GaimPresence * | |
1091 gaim_presence_new_for_conv(GaimConversation *conv) | |
1092 { | |
1093 GaimPresence *presence; | |
1094 | |
1095 g_return_val_if_fail(conv != NULL, NULL); | |
1096 | |
1097 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
1098 presence->u.chat.conv = conv; | |
10006 | 1099 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 1100 |
1101 return presence; | |
1102 } | |
6216 | 1103 |
9949 | 1104 GaimPresence * |
1105 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
1106 { | |
1107 GaimPresence *presence; | |
1108 GaimStatusBuddyKey *key; | |
10006 | 1109 GaimAccount *account; |
9949 | 1110 |
1111 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 1112 account = buddy->account; |
9949 | 1113 |
1114 key = g_new0(GaimStatusBuddyKey, 1); | |
1115 key->account = buddy->account; | |
1116 key->name = g_strdup(buddy->name); | |
10006 | 1117 |
1118 presence = g_hash_table_lookup(buddy_presences, key); | |
1119 if (presence == NULL) | |
9949 | 1120 { |
1121 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
1122 | |
1123 presence->u.buddy.name = g_strdup(buddy->name); | |
1124 presence->u.buddy.account = buddy->account; | |
10006 | 1125 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 1126 |
1127 g_hash_table_insert(buddy_presences, key, presence); | |
1128 } | |
1129 else | |
1130 { | |
1131 g_free(key->name); | |
1132 g_free(key); | |
1133 } | |
1134 | |
1135 presence->u.buddy.ref_count++; | |
1136 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
1137 buddy); | |
1138 | |
1139 return presence; | |
1140 } | |
1141 | |
1142 void | |
1143 gaim_presence_destroy(GaimPresence *presence) | |
1144 { | |
1145 g_return_if_fail(presence != NULL); | |
6216 | 1146 |
9949 | 1147 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1148 { | |
1149 GaimStatusBuddyKey key; | |
1150 | |
10077 | 1151 if(presence->u.buddy.ref_count != 0) |
1152 return; | |
9949 | 1153 |
1154 key.account = presence->u.buddy.account; | |
1155 key.name = presence->u.buddy.name; | |
1156 | |
1157 g_hash_table_remove(buddy_presences, &key); | |
1158 | |
1159 if (presence->u.buddy.name != NULL) | |
1160 g_free(presence->u.buddy.name); | |
1161 } | |
1162 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1163 { | |
1164 if (presence->u.chat.user != NULL) | |
1165 g_free(presence->u.chat.user); | |
1166 } | |
1167 | |
11638 | 1168 if (presence->statuses != NULL) { |
1169 g_list_foreach(presence->statuses, (GFunc)gaim_status_destroy, NULL); | |
9949 | 1170 g_list_free(presence->statuses); |
11638 | 1171 } |
9949 | 1172 |
1173 g_hash_table_destroy(presence->status_table); | |
1174 | |
11187 | 1175 GAIM_DBUS_UNREGISTER_POINTER(presence); |
9949 | 1176 g_free(presence); |
1177 } | |
1178 | |
10580 | 1179 /* |
1180 * TODO: Maybe we should cal gaim_presence_destroy() after we | |
1181 * decrement the ref count? I don't see why we should | |
1182 * make other places do it manually when we can do it here. | |
1183 */ | |
9949 | 1184 void |
1185 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
1186 { | |
1187 g_return_if_fail(presence != NULL); | |
1188 g_return_if_fail(buddy != NULL); | |
1189 g_return_if_fail(gaim_presence_get_context(presence) == | |
1190 GAIM_PRESENCE_CONTEXT_BUDDY); | |
1191 | |
1192 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
1193 { | |
1194 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
1195 buddy); | |
1196 presence->u.buddy.ref_count--; | |
1197 } | |
6065 | 1198 } |
1199 | |
9949 | 1200 void |
1201 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
1202 { | |
1203 g_return_if_fail(presence != NULL); | |
1204 g_return_if_fail(status != NULL); | |
1205 | |
1206 presence->statuses = g_list_append(presence->statuses, status); | |
1207 | |
1208 g_hash_table_insert(presence->status_table, | |
1209 g_strdup(gaim_status_get_id(status)), status); | |
1210 } | |
1211 | |
1212 void | |
11318 | 1213 gaim_presence_add_list(GaimPresence *presence, const GList *source_list) |
9949 | 1214 { |
1215 const GList *l; | |
1216 | |
1217 g_return_if_fail(presence != NULL); | |
1218 g_return_if_fail(source_list != NULL); | |
1219 | |
1220 for (l = source_list; l != NULL; l = l->next) | |
1221 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
1222 } | |
1223 | |
1224 void | |
1225 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
1226 gboolean active) | |
1227 { | |
1228 GaimStatus *status; | |
1229 | |
1230 g_return_if_fail(presence != NULL); | |
1231 g_return_if_fail(status_id != NULL); | |
1232 | |
1233 status = gaim_presence_get_status(presence, status_id); | |
1234 | |
1235 g_return_if_fail(status != NULL); | |
10348 | 1236 /* TODO: Should we do the following? */ |
1237 /* g_return_if_fail(active == status->active); */ | |
9949 | 1238 |
10067 | 1239 if (gaim_status_is_exclusive(status)) |
9949 | 1240 { |
1241 if (!active) | |
1242 { | |
1243 gaim_debug_warning("status", | |
1244 "Attempted to set a non-independent status " | |
1245 "(%s) inactive. Only independent statuses " | |
1246 "can be specifically marked inactive.", | |
1247 status_id); | |
1248 return; | |
1249 } | |
1250 } | |
1251 | |
1252 gaim_status_set_active(status, active); | |
1253 } | |
1254 | |
1255 void | |
1256 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
1257 { | |
10754 | 1258 gaim_presence_set_status_active(presence, status_id, TRUE); |
9949 | 1259 } |
1260 | |
1261 static void | |
1262 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
1263 time_t current_time, gboolean old_idle, gboolean idle) | |
1264 { | |
1265 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1266 GaimConversation *conv; |
9949 | 1267 |
1268 if (!old_idle && idle) | |
1269 { | |
11698 | 1270 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 1271 { |
1272 GaimLog *log = gaim_account_get_log(buddy->account); | |
1273 char *tmp = g_strdup_printf(_("%s became idle"), | |
1274 gaim_buddy_get_alias(buddy)); | |
1275 | |
1276 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1277 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1278 g_free(tmp); | |
1279 } | |
1280 } | |
1281 else if (old_idle && !idle) | |
1282 { | |
11698 | 1283 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 1284 { |
1285 GaimLog *log = gaim_account_get_log(buddy->account); | |
1286 char *tmp = g_strdup_printf(_("%s became unidle"), | |
1287 gaim_buddy_get_alias(buddy)); | |
1288 | |
1289 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1290 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1291 g_free(tmp); | |
1292 } | |
1293 } | |
1294 | |
11935
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1295 if (old_idle != idle) |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1296 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle-changed", buddy, |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1297 old_idle, idle); |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1298 |
10378 | 1299 gaim_contact_invalidate_priority_buddy(gaim_buddy_get_contact(buddy)); |
9949 | 1300 |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1301 /* 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
|
1302 * connect to buddy-[un]idle signals and update from there |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1303 */ |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1304 |
9949 | 1305 if (ops != NULL && ops->update != NULL) |
1306 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1307 |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1308 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1309 gaim_buddy_get_name(buddy), |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1310 gaim_buddy_get_account(buddy)); |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1311 if (conv) |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1312 { |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1313 GaimConversationUiOps *conv_ops; |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1314 conv_ops = gaim_conversation_get_ui_ops(conv); |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1315 if (conv_ops && conv_ops->updated) |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1316 conv_ops->updated(conv, GAIM_CONV_UPDATE_AWAY); |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1317 } |
9949 | 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 | |
1641 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
1642 gpointer data) | |
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 } |