Mercurial > pidgin
annotate src/status.c @ 12024:e67993da8a22
[gaim-migrate @ 14317]
I strongly suspect CruiseControl is going to yell at me for this.
A voice chat API, GUI + mediastreamer. This is what I'm using for Google Talk.
This doesn't actually do anything at all. There's no code in the Jabber plugin yet
to use this API (although it Works For Me). All it will do is compile and link.
If you're lucky.
To build this, you should install oRTP from Linphone, Speex and iLBC (also
from linphone, I believe). To not build this, ./configure --disable-vv.
Most of the configure.ac and Makefile.am hackery was lifted right out of
Linphone with a few modifications. It seems to work if you have everything
installed or if you --disable-vv. I haven't really tested not having
everything installed and not --disabling-vv.
It's kinda funky to include all of mediastreamer in the source tree like this,
but linphone doesn't build it as a separate library. I'll probably wind up
writing them a patch to build it as a .so so we can link it dynamically instead.
This code certainly isn't finished. It'll adapt as I progress on the Google code,
but it's certainly of more use here in CVS than in my personal tree.
committer: Tailor Script <tailor@pidgin.im>
| author | Sean Egan <seanegan@gmail.com> |
|---|---|
| date | Wed, 09 Nov 2005 08:07:20 +0000 |
| parents | 5a63ea24ac83 |
| children | 355c7acbb61d |
| 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_BUDDY) | |
| 663 { | |
| 664 const GList *l; | |
| 665 | |
| 666 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
| 667 { | |
| 668 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
| 669 old_status, new_status); | |
| 670 } | |
| 671 } | |
| 672 } | |
| 673 | |
| 10204 | 674 static void |
| 675 status_has_changed(GaimStatus *status) | |
| 9949 | 676 { |
| 677 GaimPresence *presence; | |
| 678 GaimStatus *old_status; | |
| 679 | |
| 680 presence = gaim_status_get_presence(status); | |
| 681 | |
| 10204 | 682 /* |
| 683 * If this status is exclusive, then we must be setting it to "active." | |
| 684 * Since we are setting it to active, we want to set the currently | |
| 685 * active status to "inactive." | |
| 686 */ | |
| 687 if (gaim_status_is_exclusive(status)) | |
| 9949 | 688 { |
| 10754 | 689 old_status = gaim_presence_get_active_status(presence); |
| 10760 | 690 if (old_status != NULL && (old_status != status)) |
| 10754 | 691 old_status->active = FALSE; |
| 692 presence->active_status = status; | |
| 9949 | 693 } |
| 10754 | 694 else |
| 695 old_status = NULL; | |
| 9949 | 696 |
| 10204 | 697 notify_status_update(presence, old_status, status); |
| 698 } | |
| 699 | |
| 700 void | |
| 701 gaim_status_set_active(GaimStatus *status, gboolean active) | |
| 702 { | |
| 10754 | 703 gaim_status_set_active_with_attrs(status, active, NULL); |
| 10204 | 704 } |
| 705 | |
| 11249 | 706 /* |
| 707 * This used to parse the va_list directly, but now it creates a GList | |
| 708 * and passes it to gaim_status_set_active_with_attrs_list(). That | |
| 709 * function was created because accounts.c needs to pass a GList of | |
| 710 * attributes to the status API. | |
| 711 */ | |
| 10204 | 712 void |
| 713 gaim_status_set_active_with_attrs(GaimStatus *status, gboolean active, va_list args) | |
| 714 { | |
| 11249 | 715 GList *attrs = NULL; |
| 716 const gchar *id; | |
| 717 gpointer data; | |
| 718 | |
| 719 if (args != NULL) | |
| 720 { | |
| 721 while ((id = va_arg(args, const char *)) != NULL) | |
| 722 { | |
| 723 attrs = g_list_append(attrs, (char *)id); | |
| 724 data = va_arg(args, void *); | |
| 725 attrs = g_list_append(attrs, data); | |
| 726 } | |
| 727 } | |
| 728 gaim_status_set_active_with_attrs_list(status, active, attrs); | |
| 729 g_list_free(attrs); | |
| 730 } | |
| 731 | |
| 732 void | |
| 733 gaim_status_set_active_with_attrs_list(GaimStatus *status, gboolean active, | |
| 734 const GList *attrs) | |
| 735 { | |
| 10204 | 736 gboolean changed = FALSE; |
| 737 const gchar *id; | |
| 738 | |
| 10714 | 739 g_return_if_fail(status != NULL); |
| 740 | |
| 10204 | 741 if (!active && gaim_status_is_exclusive(status)) |
| 742 { | |
| 743 gaim_debug_error("status", | |
| 744 "Cannot deactivate an exclusive status (%s).\n", | |
| 745 gaim_status_get_id(status)); | |
| 746 return; | |
| 747 } | |
| 748 | |
| 749 if (status->active != active) | |
| 10738 | 750 { |
| 10204 | 751 changed = TRUE; |
| 10738 | 752 } |
| 10204 | 753 |
| 9949 | 754 status->active = active; |
| 6065 | 755 |
| 10204 | 756 /* Set any attributes */ |
| 11249 | 757 while (attrs) |
| 10204 | 758 { |
| 759 GaimValue *value; | |
| 11249 | 760 |
| 761 id = attrs->data; | |
| 762 attrs = attrs->next; | |
| 10204 | 763 value = gaim_status_get_attr_value(status, id); |
| 10713 | 764 if (value == NULL) |
| 765 { | |
| 766 gaim_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
| 10714 | 767 "not supported.\n", id, status->type->name); |
| 10713 | 768 /* Skip over the data and move on to the next attribute */ |
| 11249 | 769 attrs = attrs->next; |
| 10713 | 770 continue; |
| 771 } | |
| 772 | |
| 10204 | 773 if (value->type == GAIM_TYPE_STRING) |
| 774 { | |
| 11249 | 775 const gchar *string_data = attrs->data; |
| 776 attrs = attrs->next; | |
| 10204 | 777 if (((string_data == NULL) && (value->data.string_data == NULL)) || |
| 778 ((string_data != NULL) && (value->data.string_data != NULL) && | |
| 779 !strcmp(string_data, value->data.string_data))) | |
| 780 { | |
| 781 continue; | |
| 782 } | |
| 783 gaim_status_set_attr_string(status, id, string_data); | |
| 784 changed = TRUE; | |
| 785 } | |
| 786 else if (value->type == GAIM_TYPE_INT) | |
| 787 { | |
| 11586 | 788 int int_data = GPOINTER_TO_INT(attrs->data); |
| 11249 | 789 attrs = attrs->next; |
| 10204 | 790 if (int_data == value->data.int_data) |
| 791 continue; | |
| 792 gaim_status_set_attr_int(status, id, int_data); | |
| 793 changed = TRUE; | |
| 794 } | |
| 795 else if (value->type == GAIM_TYPE_BOOLEAN) | |
| 796 { | |
| 11586 | 797 gboolean boolean_data = GPOINTER_TO_INT(attrs->data); |
| 11249 | 798 attrs = attrs->next; |
| 10204 | 799 if (boolean_data == value->data.boolean_data) |
| 800 continue; | |
| 801 gaim_status_set_attr_int(status, id, boolean_data); | |
| 802 changed = TRUE; | |
| 803 } | |
| 804 else | |
| 805 { | |
| 806 /* We don't know what the data is--skip over it */ | |
| 11249 | 807 attrs = attrs->next; |
| 10204 | 808 } |
| 809 } | |
| 810 | |
| 811 if (!changed) | |
| 812 return; | |
| 813 status_has_changed(status); | |
| 9949 | 814 } |
| 815 | |
| 816 void | |
| 817 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
| 818 gboolean value) | |
| 819 { | |
| 820 GaimStatusType *status_type; | |
| 821 GaimValue *attr_value; | |
| 822 | |
| 823 g_return_if_fail(status != NULL); | |
| 824 g_return_if_fail(id != NULL); | |
| 825 | |
| 826 status_type = gaim_status_get_type(status); | |
| 827 | |
| 10197 | 828 /* Make sure this attribute exists and is the correct type. */ |
| 829 attr_value = gaim_status_get_attr_value(status, id); | |
| 830 g_return_if_fail(attr_value != NULL); | |
| 9949 | 831 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); |
| 832 | |
| 833 gaim_value_set_boolean(attr_value, value); | |
| 834 } | |
| 835 | |
| 836 void | |
| 837 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
| 838 { | |
| 839 GaimStatusType *status_type; | |
| 840 GaimValue *attr_value; | |
| 841 | |
| 842 g_return_if_fail(status != NULL); | |
| 843 g_return_if_fail(id != NULL); | |
| 844 | |
| 845 status_type = gaim_status_get_type(status); | |
| 846 | |
| 10197 | 847 /* Make sure this attribute exists and is the correct type. */ |
| 848 attr_value = gaim_status_get_attr_value(status, id); | |
| 849 g_return_if_fail(attr_value != NULL); | |
| 9949 | 850 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); |
| 851 | |
| 852 gaim_value_set_int(attr_value, value); | |
| 6065 | 853 } |
| 854 | |
| 9949 | 855 void |
| 856 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
| 857 const char *value) | |
| 858 { | |
| 859 GaimStatusType *status_type; | |
| 860 GaimValue *attr_value; | |
| 861 | |
| 862 g_return_if_fail(status != NULL); | |
| 863 g_return_if_fail(id != NULL); | |
| 864 | |
| 865 status_type = gaim_status_get_type(status); | |
| 866 | |
| 10197 | 867 /* Make sure this attribute exists and is the correct type. */ |
| 10196 | 868 attr_value = gaim_status_get_attr_value(status, id); |
| 10197 | 869 g_return_if_fail(attr_value != NULL); |
| 9949 | 870 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); |
| 871 | |
| 872 gaim_value_set_string(attr_value, value); | |
| 873 } | |
| 874 | |
| 875 GaimStatusType * | |
| 876 gaim_status_get_type(const GaimStatus *status) | |
| 877 { | |
| 878 g_return_val_if_fail(status != NULL, NULL); | |
| 879 | |
| 880 return status->type; | |
| 881 } | |
| 882 | |
| 883 GaimPresence * | |
| 884 gaim_status_get_presence(const GaimStatus *status) | |
| 6065 | 885 { |
| 9949 | 886 g_return_val_if_fail(status != NULL, NULL); |
| 887 | |
| 888 return status->presence; | |
| 889 } | |
| 890 | |
| 891 const char * | |
| 892 gaim_status_get_id(const GaimStatus *status) | |
| 893 { | |
| 894 g_return_val_if_fail(status != NULL, NULL); | |
| 895 | |
| 896 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
| 897 } | |
| 898 | |
| 899 const char * | |
| 900 gaim_status_get_name(const GaimStatus *status) | |
| 901 { | |
| 902 g_return_val_if_fail(status != NULL, NULL); | |
| 903 | |
| 904 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
| 905 } | |
| 906 | |
| 907 gboolean | |
| 908 gaim_status_is_independent(const GaimStatus *status) | |
| 909 { | |
| 910 g_return_val_if_fail(status != NULL, FALSE); | |
| 911 | |
| 912 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
| 913 } | |
| 914 | |
| 915 gboolean | |
| 10067 | 916 gaim_status_is_exclusive(const GaimStatus *status) |
| 917 { | |
| 918 g_return_val_if_fail(status != NULL, FALSE); | |
| 919 | |
| 920 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
| 921 } | |
| 922 | |
| 923 gboolean | |
| 9949 | 924 gaim_status_is_available(const GaimStatus *status) |
| 925 { | |
| 926 g_return_val_if_fail(status != NULL, FALSE); | |
| 927 | |
| 928 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
| 929 } | |
| 6216 | 930 |
| 9949 | 931 gboolean |
| 932 gaim_status_is_active(const GaimStatus *status) | |
| 933 { | |
| 934 g_return_val_if_fail(status != NULL, FALSE); | |
| 935 | |
| 936 return status->active; | |
| 937 } | |
| 938 | |
|
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
939 gboolean |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
940 gaim_status_is_online(const GaimStatus *status) |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
941 { |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
942 GaimStatusPrimitive primitive; |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
943 |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
944 g_return_val_if_fail( status != NULL, FALSE); |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
945 |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
946 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
947 |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
948 return (primitive != GAIM_STATUS_UNSET && |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
949 primitive != GAIM_STATUS_OFFLINE); |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
950 } |
|
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
951 |
| 9949 | 952 GaimValue * |
| 953 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
| 954 { | |
| 955 GaimStatusType *status_type; | |
| 956 GaimStatusAttr *attr; | |
| 957 | |
| 958 g_return_val_if_fail(status != NULL, NULL); | |
| 959 g_return_val_if_fail(id != NULL, NULL); | |
| 960 | |
| 961 status_type = gaim_status_get_type(status); | |
| 962 | |
| 963 /* Make sure this attribute exists. */ | |
| 964 attr = gaim_status_type_get_attr(status_type, id); | |
| 965 g_return_val_if_fail(attr != NULL, NULL); | |
| 966 | |
| 967 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
| 968 } | |
| 969 | |
| 970 gboolean | |
| 971 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
| 972 { | |
| 973 const GaimValue *value; | |
| 974 | |
| 975 g_return_val_if_fail(status != NULL, FALSE); | |
| 976 g_return_val_if_fail(id != NULL, FALSE); | |
| 977 | |
| 978 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
| 979 return FALSE; | |
| 980 | |
| 10197 | 981 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_BOOLEAN, FALSE); |
| 9949 | 982 |
| 983 return gaim_value_get_boolean(value); | |
| 984 } | |
| 985 | |
| 986 int | |
| 987 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
| 988 { | |
| 989 const GaimValue *value; | |
| 990 | |
| 10507 | 991 g_return_val_if_fail(status != NULL, 0); |
| 992 g_return_val_if_fail(id != NULL, 0); | |
| 9949 | 993 |
| 994 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
| 10507 | 995 return 0; |
| 9949 | 996 |
| 997 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
| 998 | |
| 999 return gaim_value_get_int(value); | |
| 1000 } | |
| 1001 | |
| 1002 const char * | |
| 1003 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
| 1004 { | |
| 1005 const GaimValue *value; | |
| 1006 | |
| 10507 | 1007 g_return_val_if_fail(status != NULL, NULL); |
| 1008 g_return_val_if_fail(id != NULL, NULL); | |
| 9949 | 1009 |
| 1010 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
| 10504 | 1011 return NULL; |
| 9949 | 1012 |
| 1013 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
| 1014 | |
| 1015 return gaim_value_get_string(value); | |
| 1016 } | |
| 1017 | |
| 1018 gint | |
| 1019 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
| 1020 { | |
| 1021 GaimStatusType *type1, *type2; | |
| 1022 int score1 = 0, score2 = 0; | |
| 6065 | 1023 |
| 9949 | 1024 if ((status1 == NULL && status2 == NULL) || |
| 1025 (status1 == status2)) | |
| 1026 { | |
| 1027 return 0; | |
| 1028 } | |
| 1029 else if (status1 == NULL) | |
| 1030 return 1; | |
| 1031 else if (status2 == NULL) | |
| 1032 return -1; | |
| 1033 | |
| 1034 type1 = gaim_status_get_type(status1); | |
| 1035 type2 = gaim_status_get_type(status2); | |
| 1036 | |
| 1037 if (gaim_status_is_active(status1)) | |
| 1038 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
| 1039 | |
| 1040 if (gaim_status_is_active(status2)) | |
| 1041 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
| 1042 | |
| 1043 if (score1 > score2) | |
| 1044 return -1; | |
| 1045 else if (score1 < score2) | |
| 1046 return 1; | |
| 1047 | |
| 1048 return 0; | |
| 1049 } | |
| 1050 | |
| 1051 | |
| 1052 /************************************************************************** | |
| 1053 * GaimPresence API | |
| 1054 **************************************************************************/ | |
| 1055 GaimPresence * | |
| 1056 gaim_presence_new(GaimPresenceContext context) | |
| 1057 { | |
| 1058 GaimPresence *presence; | |
| 1059 | |
| 1060 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
| 1061 | |
| 1062 presence = g_new0(GaimPresence, 1); | |
| 11187 | 1063 GAIM_DBUS_REGISTER_POINTER(presence, GaimPresence); |
| 9949 | 1064 |
| 1065 presence->context = context; | |
| 1066 | |
| 1067 presence->status_table = | |
| 10009 | 1068 g_hash_table_new_full(g_str_hash, g_str_equal, |
| 11638 | 1069 g_free, NULL); |
| 9949 | 1070 |
| 1071 return presence; | |
| 1072 } | |
| 1073 | |
| 1074 GaimPresence * | |
| 1075 gaim_presence_new_for_account(GaimAccount *account) | |
| 1076 { | |
| 10012 | 1077 GaimPresence *presence = NULL; |
| 9949 | 1078 g_return_val_if_fail(account != NULL, NULL); |
| 1079 | |
| 1080 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
| 1081 presence->u.account = account; | |
| 10006 | 1082 presence->statuses = gaim_prpl_get_statuses(account, presence); |
| 9949 | 1083 |
| 1084 return presence; | |
| 1085 } | |
| 1086 | |
| 1087 GaimPresence * | |
| 1088 gaim_presence_new_for_conv(GaimConversation *conv) | |
| 1089 { | |
| 1090 GaimPresence *presence; | |
| 1091 | |
| 1092 g_return_val_if_fail(conv != NULL, NULL); | |
| 1093 | |
| 1094 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
| 1095 presence->u.chat.conv = conv; | |
| 10006 | 1096 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
| 9949 | 1097 |
| 1098 return presence; | |
| 1099 } | |
| 6216 | 1100 |
| 9949 | 1101 GaimPresence * |
| 1102 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
| 1103 { | |
| 1104 GaimPresence *presence; | |
| 1105 GaimStatusBuddyKey *key; | |
| 10006 | 1106 GaimAccount *account; |
| 9949 | 1107 |
| 1108 g_return_val_if_fail(buddy != NULL, NULL); | |
| 10012 | 1109 account = buddy->account; |
| 9949 | 1110 |
| 1111 key = g_new0(GaimStatusBuddyKey, 1); | |
| 1112 key->account = buddy->account; | |
| 1113 key->name = g_strdup(buddy->name); | |
| 10006 | 1114 |
| 1115 presence = g_hash_table_lookup(buddy_presences, key); | |
| 1116 if (presence == NULL) | |
| 9949 | 1117 { |
| 1118 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
| 1119 | |
| 1120 presence->u.buddy.name = g_strdup(buddy->name); | |
| 1121 presence->u.buddy.account = buddy->account; | |
| 10006 | 1122 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
| 9949 | 1123 |
| 1124 g_hash_table_insert(buddy_presences, key, presence); | |
| 1125 } | |
| 1126 else | |
| 1127 { | |
| 1128 g_free(key->name); | |
| 1129 g_free(key); | |
| 1130 } | |
| 1131 | |
| 1132 presence->u.buddy.ref_count++; | |
| 1133 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
| 1134 buddy); | |
| 1135 | |
| 1136 return presence; | |
| 1137 } | |
| 1138 | |
| 1139 void | |
| 1140 gaim_presence_destroy(GaimPresence *presence) | |
| 1141 { | |
| 1142 g_return_if_fail(presence != NULL); | |
| 6216 | 1143 |
| 9949 | 1144 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
| 1145 { | |
| 1146 GaimStatusBuddyKey key; | |
| 1147 | |
| 10077 | 1148 if(presence->u.buddy.ref_count != 0) |
| 1149 return; | |
| 9949 | 1150 |
| 1151 key.account = presence->u.buddy.account; | |
| 1152 key.name = presence->u.buddy.name; | |
| 1153 | |
| 1154 g_hash_table_remove(buddy_presences, &key); | |
| 1155 | |
| 1156 if (presence->u.buddy.name != NULL) | |
| 1157 g_free(presence->u.buddy.name); | |
| 1158 } | |
| 1159 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
| 1160 { | |
| 1161 if (presence->u.chat.user != NULL) | |
| 1162 g_free(presence->u.chat.user); | |
| 1163 } | |
| 1164 | |
| 11638 | 1165 if (presence->statuses != NULL) { |
| 1166 g_list_foreach(presence->statuses, (GFunc)gaim_status_destroy, NULL); | |
| 9949 | 1167 g_list_free(presence->statuses); |
| 11638 | 1168 } |
| 9949 | 1169 |
| 1170 g_hash_table_destroy(presence->status_table); | |
| 1171 | |
| 11187 | 1172 GAIM_DBUS_UNREGISTER_POINTER(presence); |
| 9949 | 1173 g_free(presence); |
| 1174 } | |
| 1175 | |
| 10580 | 1176 /* |
| 1177 * TODO: Maybe we should cal gaim_presence_destroy() after we | |
| 1178 * decrement the ref count? I don't see why we should | |
| 1179 * make other places do it manually when we can do it here. | |
| 1180 */ | |
| 9949 | 1181 void |
| 1182 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
| 1183 { | |
| 1184 g_return_if_fail(presence != NULL); | |
| 1185 g_return_if_fail(buddy != NULL); | |
| 1186 g_return_if_fail(gaim_presence_get_context(presence) == | |
| 1187 GAIM_PRESENCE_CONTEXT_BUDDY); | |
| 1188 | |
| 1189 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
| 1190 { | |
| 1191 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
| 1192 buddy); | |
| 1193 presence->u.buddy.ref_count--; | |
| 1194 } | |
| 6065 | 1195 } |
| 1196 | |
| 9949 | 1197 void |
| 1198 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
| 1199 { | |
| 1200 g_return_if_fail(presence != NULL); | |
| 1201 g_return_if_fail(status != NULL); | |
| 1202 | |
| 1203 presence->statuses = g_list_append(presence->statuses, status); | |
| 1204 | |
| 1205 g_hash_table_insert(presence->status_table, | |
| 1206 g_strdup(gaim_status_get_id(status)), status); | |
| 1207 } | |
| 1208 | |
| 1209 void | |
| 11318 | 1210 gaim_presence_add_list(GaimPresence *presence, const GList *source_list) |
| 9949 | 1211 { |
| 1212 const GList *l; | |
| 1213 | |
| 1214 g_return_if_fail(presence != NULL); | |
| 1215 g_return_if_fail(source_list != NULL); | |
| 1216 | |
| 1217 for (l = source_list; l != NULL; l = l->next) | |
| 1218 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
| 1219 } | |
| 1220 | |
| 1221 void | |
| 1222 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
| 1223 gboolean active) | |
| 1224 { | |
| 1225 GaimStatus *status; | |
| 1226 | |
| 1227 g_return_if_fail(presence != NULL); | |
| 1228 g_return_if_fail(status_id != NULL); | |
| 1229 | |
| 1230 status = gaim_presence_get_status(presence, status_id); | |
| 1231 | |
| 1232 g_return_if_fail(status != NULL); | |
| 10348 | 1233 /* TODO: Should we do the following? */ |
| 1234 /* g_return_if_fail(active == status->active); */ | |
| 9949 | 1235 |
| 10067 | 1236 if (gaim_status_is_exclusive(status)) |
| 9949 | 1237 { |
| 1238 if (!active) | |
| 1239 { | |
| 1240 gaim_debug_warning("status", | |
| 1241 "Attempted to set a non-independent status " | |
| 1242 "(%s) inactive. Only independent statuses " | |
| 1243 "can be specifically marked inactive.", | |
| 1244 status_id); | |
| 1245 return; | |
| 1246 } | |
| 1247 } | |
| 1248 | |
| 1249 gaim_status_set_active(status, active); | |
| 1250 } | |
| 1251 | |
| 1252 void | |
| 1253 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
| 1254 { | |
| 10754 | 1255 gaim_presence_set_status_active(presence, status_id, TRUE); |
| 9949 | 1256 } |
| 1257 | |
| 1258 static void | |
| 1259 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
| 1260 time_t current_time, gboolean old_idle, gboolean idle) | |
| 1261 { | |
| 1262 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
|
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1263 GaimConversation *conv; |
| 9949 | 1264 |
| 1265 if (!old_idle && idle) | |
| 1266 { | |
| 11698 | 1267 if (gaim_prefs_get_bool("/core/logging/log_system")) |
| 9949 | 1268 { |
| 1269 GaimLog *log = gaim_account_get_log(buddy->account); | |
| 1270 char *tmp = g_strdup_printf(_("%s became idle"), | |
| 1271 gaim_buddy_get_alias(buddy)); | |
| 1272 | |
| 1273 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
| 1274 gaim_buddy_get_alias(buddy), current_time, tmp); | |
| 1275 g_free(tmp); | |
| 1276 } | |
| 1277 } | |
| 1278 else if (old_idle && !idle) | |
| 1279 { | |
| 11698 | 1280 if (gaim_prefs_get_bool("/core/logging/log_system")) |
| 9949 | 1281 { |
| 1282 GaimLog *log = gaim_account_get_log(buddy->account); | |
| 1283 char *tmp = g_strdup_printf(_("%s became unidle"), | |
| 1284 gaim_buddy_get_alias(buddy)); | |
| 1285 | |
| 1286 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
| 1287 gaim_buddy_get_alias(buddy), current_time, tmp); | |
| 1288 g_free(tmp); | |
| 1289 } | |
| 1290 } | |
| 1291 | |
|
11935
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1292 if (old_idle != idle) |
|
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1293 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle-changed", buddy, |
|
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1294 old_idle, idle); |
|
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1295 |
| 10378 | 1296 gaim_contact_invalidate_priority_buddy(gaim_buddy_get_contact(buddy)); |
| 9949 | 1297 |
|
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1298 /* 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
|
1299 * connect to buddy-[un]idle signals and update from there |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1300 */ |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1301 |
| 9949 | 1302 if (ops != NULL && ops->update != NULL) |
| 1303 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
|
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1304 |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1305 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1306 gaim_buddy_get_name(buddy), |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1307 gaim_buddy_get_account(buddy)); |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1308 if (conv) |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1309 { |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1310 GaimConversationUiOps *conv_ops; |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1311 conv_ops = gaim_conversation_get_ui_ops(conv); |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1312 if (conv_ops && conv_ops->updated) |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1313 conv_ops->updated(conv, GAIM_CONV_UPDATE_AWAY); |
|
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1314 } |
| 9949 | 1315 } |
| 1316 | |
| 1317 void | |
| 1318 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
| 1319 { | |
| 1320 gboolean old_idle; | |
| 1321 | |
| 1322 g_return_if_fail(presence != NULL); | |
| 1323 | |
| 1324 if (presence->idle == idle && presence->idle_time == idle_time) | |
| 1325 return; | |
| 1326 | |
| 1327 old_idle = presence->idle; | |
| 1328 presence->idle = idle; | |
| 1329 presence->idle_time = (idle ? idle_time : 0); | |
| 1330 | |
| 1331 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
| 1332 { | |
| 1333 const GList *l; | |
| 1334 time_t current_time = time(NULL); | |
| 1335 | |
| 1336 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
| 1337 { | |
| 1338 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
| 1339 old_idle, idle); | |
| 1340 } | |
| 1341 } | |
|
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1342 else if(gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_ACCOUNT) |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1343 { |
| 11975 | 1344 GaimAccount *account; |
| 1345 GaimLog *log; | |
| 1346 char *msg; | |
| 1347 GaimConnection *gc; | |
|
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1348 GaimPluginProtocolInfo *prpl_info = NULL; |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1349 |
| 11975 | 1350 account = gaim_presence_get_account(presence); |
| 1351 log = gaim_account_get_log(account); | |
| 1352 | |
| 1353 if (idle) | |
| 1354 msg = g_strdup_printf(_("+++ %s became idle"), gaim_account_get_username(account)); | |
| 1355 else | |
| 1356 msg = g_strdup_printf(_("+++ %s became unidle"), gaim_account_get_username(account)); | |
| 1357 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
| 1358 gaim_account_get_username(account), | |
| 1359 idle_time, msg); | |
| 1360 g_free(msg); | |
| 1361 | |
| 1362 gc = gaim_account_get_connection(account); | |
| 1363 | |
|
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1364 if (gc != NULL && gc->prpl != NULL) |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1365 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1366 |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1367 if (prpl_info && g_list_find(gaim_connections_get_all(), gc) && |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1368 prpl_info->set_idle) |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1369 prpl_info->set_idle(gc, time(NULL) - idle_time); |
|
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1370 } |
| 9949 | 1371 } |
| 1372 | |
| 1373 void | |
| 10006 | 1374 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
| 1375 { | |
| 1376 g_return_if_fail(presence != NULL); | |
| 1377 | |
| 1378 if (presence->login_time == login_time) | |
| 1379 return; | |
| 1380 | |
| 1381 presence->login_time = login_time; | |
| 1382 } | |
| 1383 | |
| 9949 | 1384 GaimPresenceContext |
| 1385 gaim_presence_get_context(const GaimPresence *presence) | |
| 1386 { | |
| 1387 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
| 1388 | |
| 1389 return presence->context; | |
| 1390 } | |
| 1391 | |
| 1392 GaimAccount * | |
| 1393 gaim_presence_get_account(const GaimPresence *presence) | |
| 1394 { | |
| 1395 GaimPresenceContext context; | |
| 1396 | |
| 1397 g_return_val_if_fail(presence != NULL, NULL); | |
| 1398 | |
| 1399 context = gaim_presence_get_context(presence); | |
| 1400 | |
| 1401 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
| 1402 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
| 1403 | |
| 1404 return presence->u.account; | |
| 1405 } | |
| 1406 | |
| 1407 GaimConversation * | |
| 1408 gaim_presence_get_conversation(const GaimPresence *presence) | |
| 1409 { | |
| 1410 g_return_val_if_fail(presence != NULL, NULL); | |
| 1411 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
| 1412 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
| 1413 | |
| 1414 return presence->u.chat.conv; | |
| 1415 } | |
| 1416 | |
| 1417 const char * | |
| 1418 gaim_presence_get_chat_user(const GaimPresence *presence) | |
| 1419 { | |
| 1420 g_return_val_if_fail(presence != NULL, NULL); | |
| 1421 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
| 1422 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
| 1423 | |
| 1424 return presence->u.chat.user; | |
| 1425 } | |
| 1426 | |
| 1427 const GList * | |
| 1428 gaim_presence_get_buddies(const GaimPresence *presence) | |
| 1429 { | |
| 1430 g_return_val_if_fail(presence != NULL, NULL); | |
| 1431 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
| 1432 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
| 1433 | |
| 1434 return presence->u.buddy.buddies; | |
| 1435 } | |
| 1436 | |
| 1437 const GList * | |
| 1438 gaim_presence_get_statuses(const GaimPresence *presence) | |
| 1439 { | |
| 1440 g_return_val_if_fail(presence != NULL, NULL); | |
| 1441 | |
| 1442 return presence->statuses; | |
| 1443 } | |
| 1444 | |
| 1445 GaimStatus * | |
| 1446 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
| 1447 { | |
| 1448 GaimStatus *status; | |
| 10006 | 1449 const GList *l = NULL; |
| 9949 | 1450 |
| 1451 g_return_val_if_fail(presence != NULL, NULL); | |
| 1452 g_return_val_if_fail(status_id != NULL, NULL); | |
| 1453 | |
| 10006 | 1454 /* What's the purpose of this hash table? */ |
| 10012 | 1455 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
| 10006 | 1456 status_id); |
| 10012 | 1457 |
| 10006 | 1458 if (status == NULL) { |
| 10012 | 1459 for (l = gaim_presence_get_statuses(presence); |
| 10006 | 1460 l != NULL && status == NULL; l = l->next) |
| 1461 { | |
| 1462 GaimStatus *temp_status = l->data; | |
| 10012 | 1463 |
| 10006 | 1464 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
| 1465 status = temp_status; | |
| 1466 } | |
| 1467 | |
| 1468 if (status != NULL) | |
| 1469 g_hash_table_insert(presence->status_table, | |
| 1470 g_strdup(gaim_status_get_id(status)), status); | |
| 10012 | 1471 } |
| 9949 | 1472 |
| 1473 return status; | |
| 1474 } | |
| 1475 | |
| 1476 GaimStatus * | |
| 1477 gaim_presence_get_active_status(const GaimPresence *presence) | |
| 1478 { | |
| 1479 g_return_val_if_fail(presence != NULL, NULL); | |
| 1480 | |
| 1481 return presence->active_status; | |
| 1482 } | |
| 1483 | |
| 1484 gboolean | |
| 1485 gaim_presence_is_available(const GaimPresence *presence) | |
| 1486 { | |
| 1487 GaimStatus *status; | |
| 1488 | |
| 1489 g_return_val_if_fail(presence != NULL, FALSE); | |
| 1490 | |
| 1491 status = gaim_presence_get_active_status(presence); | |
| 1492 | |
| 1493 return ((status != NULL && gaim_status_is_available(status)) && | |
| 1494 !gaim_presence_is_idle(presence)); | |
| 1495 } | |
| 1496 | |
| 1497 gboolean | |
| 1498 gaim_presence_is_online(const GaimPresence *presence) | |
| 1499 { | |
| 1500 GaimStatus *status; | |
| 1501 | |
| 1502 g_return_val_if_fail(presence != NULL, FALSE); | |
| 1503 | |
| 1504 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
| 1505 return FALSE; | |
| 1506 | |
|
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1507 return gaim_status_is_online(status); |
| 9949 | 1508 } |
| 1509 | |
| 1510 gboolean | |
| 1511 gaim_presence_is_status_active(const GaimPresence *presence, | |
| 1512 const char *status_id) | |
| 1513 { | |
| 1514 GaimStatus *status; | |
| 1515 | |
| 1516 g_return_val_if_fail(presence != NULL, FALSE); | |
| 1517 g_return_val_if_fail(status_id != NULL, FALSE); | |
| 1518 | |
| 1519 status = gaim_presence_get_status(presence, status_id); | |
| 1520 | |
| 1521 return (status != NULL && gaim_status_is_active(status)); | |
| 1522 } | |
| 1523 | |
| 1524 gboolean | |
| 1525 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
| 1526 GaimStatusPrimitive primitive) | |
| 1527 { | |
| 1528 GaimStatus *status; | |
| 1529 GaimStatusType *status_type; | |
| 1530 | |
| 1531 g_return_val_if_fail(presence != NULL, FALSE); | |
| 1532 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
| 1533 | |
| 1534 status = gaim_presence_get_active_status(presence); | |
| 1535 status_type = gaim_status_get_type(status); | |
| 1536 | |
| 1537 if (gaim_status_type_get_primitive(status_type) == primitive) | |
| 1538 return TRUE; | |
| 6065 | 1539 |
| 1540 return FALSE; | |
| 1541 } | |
| 1542 | |
| 9949 | 1543 gboolean |
| 1544 gaim_presence_is_idle(const GaimPresence *presence) | |
| 6065 | 1545 { |
| 9949 | 1546 g_return_val_if_fail(presence != NULL, FALSE); |
| 1547 | |
| 11634 | 1548 return gaim_presence_is_online(presence) && presence->idle; |
| 6065 | 1549 } |
| 1550 | |
| 9949 | 1551 time_t |
| 1552 gaim_presence_get_idle_time(const GaimPresence *presence) | |
| 6065 | 1553 { |
| 9949 | 1554 g_return_val_if_fail(presence != NULL, 0); |
| 6065 | 1555 |
| 9949 | 1556 return presence->idle_time; |
| 1557 } | |
| 6065 | 1558 |
| 10567 | 1559 time_t |
| 1560 gaim_presence_get_login_time(const GaimPresence *presence) | |
| 1561 { | |
| 1562 g_return_val_if_fail(presence != NULL, 0); | |
| 1563 | |
| 11973 | 1564 return gaim_presence_is_online(presence) ? presence->login_time : 0; |
| 10567 | 1565 } |
| 1566 | |
| 9949 | 1567 gint |
| 1568 gaim_presence_compare(const GaimPresence *presence1, | |
| 1569 const GaimPresence *presence2) | |
| 6065 | 1570 { |
| 9949 | 1571 gboolean idle1, idle2; |
| 10860 | 1572 time_t idle_time_1, idle_time_2; |
| 9949 | 1573 int score1 = 0, score2 = 0; |
| 1574 const GList *l; | |
| 6065 | 1575 |
| 9949 | 1576 if ((presence1 == NULL && presence2 == NULL) || (presence1 == presence2)) |
| 1577 return 0; | |
| 1578 else if (presence1 == NULL) | |
|
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1579 return 1; |
| 9949 | 1580 else if (presence2 == NULL) |
|
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1581 return -1; |
| 6065 | 1582 |
| 9949 | 1583 /* Compute the score of the first set of statuses. */ |
| 1584 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
| 1585 { | |
| 1586 GaimStatus *status = (GaimStatus *)l->data; | |
| 1587 GaimStatusType *type = gaim_status_get_type(status); | |
| 6065 | 1588 |
| 9949 | 1589 if (gaim_status_is_active(status)) |
| 1590 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
| 6065 | 1591 } |
| 1592 | |
| 9949 | 1593 /* Compute the score of the second set of statuses. */ |
|
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1594 for (l = gaim_presence_get_statuses(presence2); l != NULL; l = l->next) |
| 9949 | 1595 { |
| 1596 GaimStatus *status = (GaimStatus *)l->data; | |
| 1597 GaimStatusType *type = gaim_status_get_type(status); | |
| 6065 | 1598 |
| 9949 | 1599 if (gaim_status_is_active(status)) |
| 1600 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
| 6065 | 1601 } |
| 1602 | |
| 9949 | 1603 idle1 = gaim_presence_is_idle(presence1); |
| 1604 idle2 = gaim_presence_is_idle(presence2); | |
| 6065 | 1605 |
| 9949 | 1606 if (idle1) |
| 1607 score1 += primitive_scores[SCORE_IDLE]; | |
| 6065 | 1608 |
| 9949 | 1609 if (idle2) |
| 1610 score2 += primitive_scores[SCORE_IDLE]; | |
| 6065 | 1611 |
| 10860 | 1612 idle_time_1 = time(NULL) - gaim_presence_get_idle_time(presence1); |
| 1613 idle_time_2 = time(NULL) - gaim_presence_get_idle_time(presence2); | |
| 6065 | 1614 |
| 9949 | 1615 if (idle_time_1 > idle_time_2) |
| 1616 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
| 1617 else if (idle_time_1 < idle_time_2) | |
| 1618 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
| 6065 | 1619 |
| 9949 | 1620 if (score1 < score2) |
| 1621 return 1; | |
| 1622 else if (score1 > score2) | |
| 1623 return -1; | |
| 1624 | |
| 1625 return 0; | |
| 1626 } | |
| 1627 | |
| 6065 | 1628 |
| 9949 | 1629 /************************************************************************** |
| 1630 * Status subsystem | |
| 1631 **************************************************************************/ | |
| 1632 static void | |
| 1633 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
| 1634 gpointer data) | |
| 1635 { | |
| 1636 int index = GPOINTER_TO_INT(data); | |
| 6065 | 1637 |
| 9949 | 1638 primitive_scores[index] = GPOINTER_TO_INT(value); |
| 6065 | 1639 } |
| 1640 | |
| 10519 | 1641 static guint |
| 10006 | 1642 gaim_buddy_presences_hash(gconstpointer key) |
| 1643 { | |
| 10012 | 1644 const GaimStatusBuddyKey *me = key; |
| 1645 guint ret; | |
| 1646 char *str; | |
| 1647 | |
| 1648 str = g_strdup_printf("%p%s", me->account, me->name); | |
| 1649 ret = g_str_hash(str); | |
| 1650 g_free(str); | |
| 1651 | |
| 1652 return ret; | |
| 10006 | 1653 } |
| 1654 | |
| 10519 | 1655 static gboolean |
| 10006 | 1656 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
| 1657 { | |
| 1658 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
| 1659 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
| 1660 | |
| 10012 | 1661 if(key_a->account == key_b->account && |
| 1662 !strcmp(key_a->name, key_b->name)) | |
| 10006 | 1663 return TRUE; |
| 1664 else | |
| 1665 return FALSE; | |
| 1666 } | |
| 1667 | |
| 10519 | 1668 static void |
| 1669 gaim_buddy_presences_key_free(gpointer a) | |
| 1670 { | |
| 1671 GaimStatusBuddyKey *key = (GaimStatusBuddyKey *)a; | |
| 1672 g_free(key->name); | |
| 1673 g_free(key); | |
| 1674 } | |
| 1675 | |
| 10087 | 1676 void * |
| 10418 | 1677 gaim_status_get_handle(void) { |
| 10087 | 1678 static int handle; |
| 1679 | |
| 1680 return &handle; | |
| 1681 } | |
| 1682 | |
| 9949 | 1683 void |
| 10418 | 1684 gaim_status_init(void) |
| 6065 | 1685 { |
| 10418 | 1686 void *handle = gaim_status_get_handle; |
| 10087 | 1687 |
| 9949 | 1688 gaim_prefs_add_none("/core/status"); |
| 1689 gaim_prefs_add_none("/core/status/scores"); | |
| 6065 | 1690 |
| 11654 | 1691 gaim_prefs_add_string("/core/status/current", _("Default")); |
| 11975 | 1692 gaim_prefs_add_string("/core/status/idleaway", _("Default when idle")); |
| 11654 | 1693 |
| 9949 | 1694 gaim_prefs_add_int("/core/status/scores/offline", |
| 1695 primitive_scores[GAIM_STATUS_OFFLINE]); | |
| 1696 gaim_prefs_add_int("/core/status/scores/available", | |
| 1697 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
| 1698 gaim_prefs_add_int("/core/status/scores/hidden", | |
| 1699 primitive_scores[GAIM_STATUS_HIDDEN]); | |
| 1700 gaim_prefs_add_int("/core/status/scores/away", | |
| 1701 primitive_scores[GAIM_STATUS_AWAY]); | |
| 1702 gaim_prefs_add_int("/core/status/scores/extended_away", | |
| 1703 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
| 1704 gaim_prefs_add_int("/core/status/scores/idle", | |
| 1705 primitive_scores[SCORE_IDLE]); | |
| 6065 | 1706 |
| 10087 | 1707 gaim_prefs_connect_callback(handle, "/core/status/scores/offline", |
| 9949 | 1708 score_pref_changed_cb, |
| 1709 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
| 10087 | 1710 gaim_prefs_connect_callback(handle, "/core/status/scores/available", |
| 9949 | 1711 score_pref_changed_cb, |
| 1712 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
| 10087 | 1713 gaim_prefs_connect_callback(handle, "/core/status/scores/hidden", |
| 9949 | 1714 score_pref_changed_cb, |
| 1715 GINT_TO_POINTER(GAIM_STATUS_HIDDEN)); | |
| 10087 | 1716 gaim_prefs_connect_callback(handle, "/core/status/scores/away", |
| 9949 | 1717 score_pref_changed_cb, |
| 1718 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
| 10087 | 1719 gaim_prefs_connect_callback(handle, "/core/status/scores/extended_away", |
| 9949 | 1720 score_pref_changed_cb, |
| 1721 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
| 10087 | 1722 gaim_prefs_connect_callback(handle, "/core/status/scores/idle", |
| 9949 | 1723 score_pref_changed_cb, |
| 1724 GINT_TO_POINTER(SCORE_IDLE)); | |
| 10006 | 1725 |
| 10519 | 1726 buddy_presences = g_hash_table_new_full(gaim_buddy_presences_hash, |
| 1727 gaim_buddy_presences_equal, | |
| 1728 gaim_buddy_presences_key_free, NULL); | |
| 9949 | 1729 } |
| 6065 | 1730 |
| 9949 | 1731 void |
| 10418 | 1732 gaim_status_uninit(void) |
| 9949 | 1733 { |
|
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1734 if (buddy_presences != NULL) |
|
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1735 { |
| 10077 | 1736 g_hash_table_destroy(buddy_presences); |
|
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1737 |
|
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1738 buddy_presences = NULL; |
|
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1739 } |
| 9949 | 1740 } |
