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