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