3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "glibcompat.h"
26 /**************************************************************************
28 **************************************************************************/
30 /** Private data for a presence */
38 GHashTable
*status_table
;
40 PurpleStatus
*active_status
;
41 } PurplePresencePrivate
;
43 /* Presence property enums */
51 PRES_PROP_ACTIVE_STATUS
,
55 static GParamSpec
*properties
[PRES_PROP_LAST
];
57 G_DEFINE_TYPE_WITH_PRIVATE(PurplePresence
, purple_presence
, G_TYPE_OBJECT
)
59 /**************************************************************************
60 * PurpleAccountPresence
61 **************************************************************************/
64 * PurpleAccountPresence:
66 * A presence for an account
68 struct _PurpleAccountPresence
70 PurplePresence parent
;
73 /** Private data for an account presence */
76 PurpleAccount
*account
;
77 } PurpleAccountPresencePrivate
;
79 /* Account presence property enums */
87 static GParamSpec
*ap_properties
[ACPRES_PROP_LAST
];
89 G_DEFINE_TYPE_WITH_PRIVATE(PurpleAccountPresence
, purple_account_presence
,
92 /**************************************************************************
94 **************************************************************************/
97 * PurpleBuddyPresence:
99 * A presence for a buddy
101 struct _PurpleBuddyPresence
103 PurplePresence parent
;
106 /** Private data for a buddy presence */
110 } PurpleBuddyPresencePrivate
;
112 /* Buddy presence property enums */
120 static GParamSpec
*bp_properties
[BUDPRES_PROP_LAST
];
122 G_DEFINE_TYPE_WITH_PRIVATE(PurpleBuddyPresence
, purple_buddy_presence
,
123 PURPLE_TYPE_PRESENCE
)
125 /**************************************************************************
127 **************************************************************************/
130 purple_presence_set_status_active(PurplePresence
*presence
, const char *status_id
,
133 PurpleStatus
*status
;
135 g_return_if_fail(PURPLE_IS_PRESENCE(presence
));
136 g_return_if_fail(status_id
!= NULL
);
138 status
= purple_presence_get_status(presence
, status_id
);
140 g_return_if_fail(PURPLE_IS_STATUS(status
));
141 /* TODO: Should we do the following? */
142 /* g_return_if_fail(active == status->active); */
144 if (purple_status_is_exclusive(status
))
148 purple_debug_warning("presence",
149 "Attempted to set a non-independent status "
150 "(%s) inactive. Only independent statuses "
151 "can be specifically marked inactive.",
157 purple_status_set_active(status
, active
);
161 purple_presence_switch_status(PurplePresence
*presence
, const char *status_id
)
163 purple_presence_set_status_active(presence
, status_id
, TRUE
);
167 purple_presence_set_idle(PurplePresence
*presence
, gboolean idle
, time_t idle_time
)
169 PurplePresencePrivate
*priv
= NULL
;
170 PurplePresenceClass
*klass
= NULL
;
174 g_return_if_fail(PURPLE_IS_PRESENCE(presence
));
176 priv
= purple_presence_get_instance_private(presence
);
177 klass
= PURPLE_PRESENCE_GET_CLASS(presence
);
179 if (priv
->idle
== idle
&& priv
->idle_time
== idle_time
)
182 old_idle
= priv
->idle
;
184 priv
->idle_time
= (idle
? idle_time
: 0);
186 obj
= G_OBJECT(presence
);
187 g_object_freeze_notify(obj
);
188 g_object_notify_by_pspec(obj
, properties
[PRES_PROP_IDLE
]);
189 g_object_notify_by_pspec(obj
, properties
[PRES_PROP_IDLE_TIME
]);
190 g_object_thaw_notify(obj
);
192 if (klass
->update_idle
)
193 klass
->update_idle(presence
, old_idle
);
197 purple_presence_set_login_time(PurplePresence
*presence
, time_t login_time
)
199 PurplePresencePrivate
*priv
= NULL
;
201 g_return_if_fail(PURPLE_IS_PRESENCE(presence
));
203 priv
= purple_presence_get_instance_private(presence
);
205 if (priv
->login_time
== login_time
)
208 priv
->login_time
= login_time
;
210 g_object_notify_by_pspec(G_OBJECT(presence
),
211 properties
[PRES_PROP_LOGIN_TIME
]);
215 purple_presence_get_statuses(PurplePresence
*presence
)
217 PurplePresencePrivate
*priv
= NULL
;
219 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), NULL
);
221 priv
= purple_presence_get_instance_private(presence
);
222 return priv
->statuses
;
226 purple_presence_get_status(PurplePresence
*presence
, const char *status_id
)
228 PurplePresencePrivate
*priv
= NULL
;
229 PurpleStatus
*status
;
232 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), NULL
);
233 g_return_val_if_fail(status_id
!= NULL
, NULL
);
235 priv
= purple_presence_get_instance_private(presence
);
237 /* What's the purpose of this hash table? */
238 status
= (PurpleStatus
*)g_hash_table_lookup(priv
->status_table
,
241 if (status
== NULL
) {
242 for (l
= purple_presence_get_statuses(presence
);
243 l
!= NULL
&& status
== NULL
; l
= l
->next
)
245 PurpleStatus
*temp_status
= l
->data
;
247 if (purple_strequal(status_id
, purple_status_get_id(temp_status
)))
248 status
= temp_status
;
252 g_hash_table_insert(priv
->status_table
,
253 g_strdup(purple_status_get_id(status
)), status
);
260 purple_presence_get_active_status(PurplePresence
*presence
)
262 PurplePresencePrivate
*priv
= NULL
;
264 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), NULL
);
266 priv
= purple_presence_get_instance_private(presence
);
267 return priv
->active_status
;
271 purple_presence_is_available(PurplePresence
*presence
)
273 PurpleStatus
*status
;
275 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
277 status
= purple_presence_get_active_status(presence
);
279 return ((status
!= NULL
&& purple_status_is_available(status
)) &&
280 !purple_presence_is_idle(presence
));
284 purple_presence_is_online(PurplePresence
*presence
)
286 PurpleStatus
*status
;
288 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
290 if ((status
= purple_presence_get_active_status(presence
)) == NULL
)
293 return purple_status_is_online(status
);
297 purple_presence_is_status_active(PurplePresence
*presence
,
298 const char *status_id
)
300 PurpleStatus
*status
;
302 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
303 g_return_val_if_fail(status_id
!= NULL
, FALSE
);
305 status
= purple_presence_get_status(presence
, status_id
);
307 return (status
!= NULL
&& purple_status_is_active(status
));
311 purple_presence_is_status_primitive_active(PurplePresence
*presence
,
312 PurpleStatusPrimitive primitive
)
316 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
317 g_return_val_if_fail(primitive
!= PURPLE_STATUS_UNSET
, FALSE
);
319 for (l
= purple_presence_get_statuses(presence
);
320 l
!= NULL
; l
= l
->next
)
322 PurpleStatus
*temp_status
= l
->data
;
323 PurpleStatusType
*type
= purple_status_get_status_type(temp_status
);
325 if (purple_status_type_get_primitive(type
) == primitive
&&
326 purple_status_is_active(temp_status
))
333 purple_presence_is_idle(PurplePresence
*presence
)
335 PurplePresencePrivate
*priv
= NULL
;
337 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
339 priv
= purple_presence_get_instance_private(presence
);
340 return purple_presence_is_online(presence
) && priv
->idle
;
344 purple_presence_get_idle_time(PurplePresence
*presence
)
346 PurplePresencePrivate
*priv
= NULL
;
348 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), 0);
350 priv
= purple_presence_get_instance_private(presence
);
351 return priv
->idle_time
;
355 purple_presence_get_login_time(PurplePresence
*presence
)
357 PurplePresencePrivate
*priv
= NULL
;
359 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), 0);
361 priv
= purple_presence_get_instance_private(presence
);
362 return purple_presence_is_online(presence
) ? priv
->login_time
: 0;
365 /**************************************************************************
366 * GObject code for PurplePresence
367 **************************************************************************/
369 /* Set method for GObject properties */
371 purple_presence_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
374 PurplePresence
*presence
= PURPLE_PRESENCE(obj
);
375 PurplePresencePrivate
*priv
= purple_presence_get_instance_private(presence
);
379 purple_presence_set_idle(presence
, g_value_get_boolean(value
), 0);
381 case PRES_PROP_IDLE_TIME
:
382 #if SIZEOF_TIME_T == 4
383 purple_presence_set_idle(presence
, TRUE
, g_value_get_int(value
));
384 #elif SIZEOF_TIME_T == 8
385 purple_presence_set_idle(presence
, TRUE
, g_value_get_int64(value
));
387 #error Unknown size of time_t
390 case PRES_PROP_LOGIN_TIME
:
391 #if SIZEOF_TIME_T == 4
392 purple_presence_set_login_time(presence
, g_value_get_int(value
));
393 #elif SIZEOF_TIME_T == 8
394 purple_presence_set_login_time(presence
, g_value_get_int64(value
));
396 #error Unknown size of time_t
399 case PRES_PROP_ACTIVE_STATUS
:
400 priv
->active_status
= g_value_get_object(value
);
403 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
408 /* Get method for GObject properties */
410 purple_presence_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
413 PurplePresence
*presence
= PURPLE_PRESENCE(obj
);
417 g_value_set_boolean(value
, purple_presence_is_idle(presence
));
419 case PRES_PROP_IDLE_TIME
:
420 #if SIZEOF_TIME_T == 4
421 g_value_set_int(value
, purple_presence_get_idle_time(presence
));
422 #elif SIZEOF_TIME_T == 8
423 g_value_set_int64(value
, purple_presence_get_idle_time(presence
));
425 #error Unknown size of time_t
428 case PRES_PROP_LOGIN_TIME
:
429 #if SIZEOF_TIME_T == 4
430 g_value_set_int(value
, purple_presence_get_login_time(presence
));
431 #elif SIZEOF_TIME_T == 8
432 g_value_set_int64(value
, purple_presence_get_login_time(presence
));
434 #error Unknown size of time_t
437 case PRES_PROP_STATUSES
:
438 g_value_set_pointer(value
, purple_presence_get_statuses(presence
));
440 case PRES_PROP_ACTIVE_STATUS
:
441 g_value_set_object(value
, purple_presence_get_active_status(presence
));
444 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
449 /* GObject initialization function */
451 purple_presence_init(PurplePresence
*presence
)
453 PurplePresencePrivate
*priv
= purple_presence_get_instance_private(presence
);
454 priv
->status_table
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, NULL
);
457 /* GObject dispose function */
459 purple_presence_dispose(GObject
*object
)
461 PurplePresencePrivate
*priv
=
462 purple_presence_get_instance_private(PURPLE_PRESENCE(object
));
464 if (priv
->statuses
) {
465 g_list_foreach(priv
->statuses
, (GFunc
)g_object_unref
, NULL
);
466 g_list_free(priv
->statuses
);
467 priv
->statuses
= NULL
;
470 G_OBJECT_CLASS(purple_presence_parent_class
)->dispose(object
);
473 /* GObject finalize function */
475 purple_presence_finalize(GObject
*object
)
477 PurplePresencePrivate
*priv
=
478 purple_presence_get_instance_private(PURPLE_PRESENCE(object
));
480 g_hash_table_destroy(priv
->status_table
);
482 G_OBJECT_CLASS(purple_presence_parent_class
)->finalize(object
);
485 /* Class initializer function */
486 static void purple_presence_class_init(PurplePresenceClass
*klass
)
488 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
490 obj_class
->dispose
= purple_presence_dispose
;
491 obj_class
->finalize
= purple_presence_finalize
;
493 /* Setup properties */
494 obj_class
->get_property
= purple_presence_get_property
;
495 obj_class
->set_property
= purple_presence_set_property
;
497 properties
[PRES_PROP_IDLE
] = g_param_spec_boolean("idle", "Idle",
498 "Whether the presence is in idle state.", FALSE
,
499 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
501 properties
[PRES_PROP_IDLE_TIME
] =
502 #if SIZEOF_TIME_T == 4
504 #elif SIZEOF_TIME_T == 8
507 #error Unknown size of time_t
509 ("idle-time", "Idle time",
510 "The idle time of the presence",
511 #if SIZEOF_TIME_T == 4
512 G_MININT
, G_MAXINT
, 0,
513 #elif SIZEOF_TIME_T == 8
514 G_MININT64
, G_MAXINT64
, 0,
516 #error Unknown size of time_t
518 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
520 properties
[PRES_PROP_LOGIN_TIME
] =
521 #if SIZEOF_TIME_T == 4
523 #elif SIZEOF_TIME_T == 8
526 #error Unknown size of time_t
528 ("login-time", "Login time",
529 "The login time of the presence.",
530 #if SIZEOF_TIME_T == 4
531 G_MININT
, G_MAXINT
, 0,
532 #elif SIZEOF_TIME_T == 8
533 G_MININT64
, G_MAXINT64
, 0,
535 #error Unknown size of time_t
537 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
539 properties
[PRES_PROP_STATUSES
] = g_param_spec_pointer("statuses",
541 "The list of statuses in the presence.",
542 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
544 properties
[PRES_PROP_ACTIVE_STATUS
] = g_param_spec_object("active-status",
546 "The active status for the presence.", PURPLE_TYPE_STATUS
,
547 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
549 g_object_class_install_properties(obj_class
, PRES_PROP_LAST
, properties
);
552 /**************************************************************************
553 * PurpleAccountPresence API
554 **************************************************************************/
556 purple_account_presence_update_idle(PurplePresence
*presence
, gboolean old_idle
)
558 PurpleAccount
*account
;
559 PurpleConnection
*gc
= NULL
;
560 PurpleProtocol
*protocol
= NULL
;
561 gboolean idle
= purple_presence_is_idle(presence
);
562 time_t idle_time
= purple_presence_get_idle_time(presence
);
563 time_t current_time
= time(NULL
);
565 account
= purple_account_presence_get_account(PURPLE_ACCOUNT_PRESENCE(presence
));
567 if (purple_prefs_get_bool("/purple/logging/log_system"))
569 PurpleLog
*log
= purple_account_get_log(account
, FALSE
);
577 tmp
= g_strdup_printf(_("+++ %s became idle"), purple_account_get_username(account
));
578 dt
= g_date_time_new_from_unix_local(idle_time
);
580 tmp
= g_strdup_printf(_("+++ %s became unidle"), purple_account_get_username(account
));
581 dt
= g_date_time_new_now_utc();
584 msg
= g_markup_escape_text(tmp
, -1);
586 purple_log_write(log
, PURPLE_MESSAGE_SYSTEM
,
587 purple_account_get_username(account
),
589 g_date_time_unref(dt
);
594 gc
= purple_account_get_connection(account
);
596 if(PURPLE_CONNECTION_IS_CONNECTED(gc
))
597 protocol
= purple_connection_get_protocol(gc
);
600 purple_protocol_server_iface_set_idle(protocol
, gc
, (idle
? (current_time
- idle_time
) : 0));
604 purple_account_presence_get_account(PurpleAccountPresence
*presence
)
606 PurpleAccountPresencePrivate
*priv
= NULL
;
608 g_return_val_if_fail(PURPLE_IS_ACCOUNT_PRESENCE(presence
), NULL
);
610 priv
= purple_account_presence_get_instance_private(presence
);
611 return priv
->account
;
615 purple_buddy_presence_compute_score(PurpleBuddyPresence
*buddy_presence
)
619 PurplePresence
*presence
= PURPLE_PRESENCE(buddy_presence
);
620 PurpleBuddy
*b
= purple_buddy_presence_get_buddy(buddy_presence
);
621 int *primitive_scores
= _purple_statuses_get_primitive_scores();
622 int offline_score
= purple_prefs_get_int("/purple/status/scores/offline_msg");
623 int idle_score
= purple_prefs_get_int("/purple/status/scores/idle");
625 for (l
= purple_presence_get_statuses(presence
); l
!= NULL
; l
= l
->next
) {
626 PurpleStatus
*status
= (PurpleStatus
*)l
->data
;
627 PurpleStatusType
*type
= purple_status_get_status_type(status
);
629 if (purple_status_is_active(status
)) {
630 score
+= primitive_scores
[purple_status_type_get_primitive(type
)];
631 if (!purple_status_is_online(status
)) {
632 if (b
&& purple_account_supports_offline_message(purple_buddy_get_account(b
), b
))
633 score
+= offline_score
;
637 score
+= purple_account_get_int(purple_buddy_get_account(b
), "score", 0);
638 if (purple_presence_is_idle(presence
))
644 purple_buddy_presence_compare(PurpleBuddyPresence
*buddy_presence1
,
645 PurpleBuddyPresence
*buddy_presence2
)
647 PurplePresence
*presence1
= PURPLE_PRESENCE(buddy_presence1
);
648 PurplePresence
*presence2
= PURPLE_PRESENCE(buddy_presence2
);
649 time_t idle_time_1
, idle_time_2
;
650 int score1
= 0, score2
= 0;
651 int idle_time_score
= purple_prefs_get_int("/purple/status/scores/idle_time");
653 if (presence1
== presence2
)
655 else if (presence1
== NULL
)
657 else if (presence2
== NULL
)
660 if (purple_presence_is_online(presence1
) &&
661 !purple_presence_is_online(presence2
))
663 else if (purple_presence_is_online(presence2
) &&
664 !purple_presence_is_online(presence1
))
667 /* Compute the score of the first set of statuses. */
668 score1
= purple_buddy_presence_compute_score(buddy_presence1
);
670 /* Compute the score of the second set of statuses. */
671 score2
= purple_buddy_presence_compute_score(buddy_presence2
);
673 idle_time_1
= time(NULL
) - purple_presence_get_idle_time(presence1
);
674 idle_time_2
= time(NULL
) - purple_presence_get_idle_time(presence2
);
676 if (idle_time_1
> idle_time_2
)
677 score1
+= idle_time_score
;
678 else if (idle_time_1
< idle_time_2
)
679 score2
+= idle_time_score
;
683 else if (score1
> score2
)
689 /**************************************************************************
690 * GObject code for PurpleAccountPresence
691 **************************************************************************/
693 /* Set method for GObject properties */
695 purple_account_presence_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
698 PurpleAccountPresence
*account_presence
= PURPLE_ACCOUNT_PRESENCE(obj
);
699 PurpleAccountPresencePrivate
*priv
=
700 purple_account_presence_get_instance_private(account_presence
);
703 case ACPRES_PROP_ACCOUNT
:
704 priv
->account
= g_value_get_object(value
);
707 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
712 /* Get method for GObject properties */
714 purple_account_presence_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
717 PurpleAccountPresence
*account_presence
= PURPLE_ACCOUNT_PRESENCE(obj
);
720 case ACPRES_PROP_ACCOUNT
:
721 g_value_set_object(value
,
722 purple_account_presence_get_account(account_presence
));
725 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
730 /* Called when done constructing */
732 purple_account_presence_constructed(GObject
*object
)
734 PurplePresence
*presence
= PURPLE_PRESENCE(object
);
735 PurplePresencePrivate
*parent_priv
= purple_presence_get_instance_private(presence
);
736 PurpleAccountPresencePrivate
*account_priv
=
737 purple_account_presence_get_instance_private(PURPLE_ACCOUNT_PRESENCE(presence
));
739 G_OBJECT_CLASS(purple_account_presence_parent_class
)->constructed(object
);
741 parent_priv
->statuses
= purple_protocol_get_statuses(account_priv
->account
, presence
);
744 /* Class initializer function */
745 static void purple_account_presence_class_init(PurpleAccountPresenceClass
*klass
)
747 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
749 PURPLE_PRESENCE_CLASS(klass
)->update_idle
= purple_account_presence_update_idle
;
751 obj_class
->constructed
= purple_account_presence_constructed
;
753 /* Setup properties */
754 obj_class
->get_property
= purple_account_presence_get_property
;
755 obj_class
->set_property
= purple_account_presence_set_property
;
757 ap_properties
[ACPRES_PROP_ACCOUNT
] = g_param_spec_object("account",
759 "The account that this presence is of.", PURPLE_TYPE_ACCOUNT
,
760 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
|
761 G_PARAM_STATIC_STRINGS
);
763 g_object_class_install_properties(obj_class
, ACPRES_PROP_LAST
,
768 purple_account_presence_init(PurpleAccountPresence
*presence
)
772 PurpleAccountPresence
*
773 purple_account_presence_new(PurpleAccount
*account
)
775 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
777 return g_object_new(PURPLE_TYPE_ACCOUNT_PRESENCE
,
782 /**************************************************************************
783 * PurpleBuddyPresence API
784 **************************************************************************/
786 purple_buddy_presence_update_idle(PurplePresence
*presence
, gboolean old_idle
)
788 PurpleBuddy
*buddy
= purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(presence
));
789 GDateTime
*current_time
= g_date_time_new_now_utc();
790 PurpleAccount
*account
= purple_buddy_get_account(buddy
);
791 gboolean idle
= purple_presence_is_idle(presence
);
793 if (!old_idle
&& idle
)
795 if (purple_prefs_get_bool("/purple/logging/log_system"))
797 PurpleLog
*log
= purple_account_get_log(account
, FALSE
);
802 tmp
= g_strdup_printf(_("%s became idle"),
803 purple_buddy_get_alias(buddy
));
804 tmp2
= g_markup_escape_text(tmp
, -1);
807 purple_log_write(log
, PURPLE_MESSAGE_SYSTEM
,
808 purple_buddy_get_alias(buddy
),
814 else if (old_idle
&& !idle
)
816 if (purple_prefs_get_bool("/purple/logging/log_system"))
818 PurpleLog
*log
= purple_account_get_log(account
, FALSE
);
823 tmp
= g_strdup_printf(_("%s became unidle"),
824 purple_buddy_get_alias(buddy
));
825 tmp2
= g_markup_escape_text(tmp
, -1);
828 purple_log_write(log
, PURPLE_MESSAGE_SYSTEM
,
829 purple_buddy_get_alias(buddy
),
836 if (old_idle
!= idle
)
837 purple_signal_emit(purple_blist_get_handle(), "buddy-idle-changed", buddy
,
840 purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy
));
842 /* Should this be done here? It'd perhaps make more sense to
843 * connect to buddy-[un]idle signals and update from there
846 purple_blist_update_node(purple_blist_get_default(),
847 PURPLE_BLIST_NODE(buddy
));
849 g_date_time_unref(current_time
);
853 purple_buddy_presence_get_buddy(PurpleBuddyPresence
*presence
)
855 PurpleBuddyPresencePrivate
*priv
= NULL
;
857 g_return_val_if_fail(PURPLE_IS_BUDDY_PRESENCE(presence
), NULL
);
859 priv
= purple_buddy_presence_get_instance_private(presence
);
863 /**************************************************************************
864 * GObject code for PurpleBuddyPresence
865 **************************************************************************/
867 /* Set method for GObject properties */
869 purple_buddy_presence_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
872 PurpleBuddyPresence
*buddy_presence
= PURPLE_BUDDY_PRESENCE(obj
);
873 PurpleBuddyPresencePrivate
*priv
=
874 purple_buddy_presence_get_instance_private(buddy_presence
);
877 case BUDPRES_PROP_BUDDY
:
878 priv
->buddy
= g_value_get_object(value
);
881 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
886 /* Get method for GObject properties */
888 purple_buddy_presence_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
891 PurpleBuddyPresence
*buddy_presence
= PURPLE_BUDDY_PRESENCE(obj
);
894 case BUDPRES_PROP_BUDDY
:
895 g_value_set_object(value
,
896 purple_buddy_presence_get_buddy(buddy_presence
));
899 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
904 /* Called when done constructing */
906 purple_buddy_presence_constructed(GObject
*object
)
908 PurplePresence
*presence
= PURPLE_PRESENCE(object
);
909 PurplePresencePrivate
*parent_priv
= purple_presence_get_instance_private(presence
);
910 PurpleBuddyPresencePrivate
*buddy_priv
=
911 purple_buddy_presence_get_instance_private(PURPLE_BUDDY_PRESENCE(presence
));
912 PurpleAccount
*account
;
914 G_OBJECT_CLASS(purple_buddy_presence_parent_class
)->constructed(object
);
916 account
= purple_buddy_get_account(buddy_priv
->buddy
);
917 parent_priv
->statuses
= purple_protocol_get_statuses(account
, presence
);
920 /* Class initializer function */
921 static void purple_buddy_presence_class_init(PurpleBuddyPresenceClass
*klass
)
923 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
925 PURPLE_PRESENCE_CLASS(klass
)->update_idle
= purple_buddy_presence_update_idle
;
927 obj_class
->constructed
= purple_buddy_presence_constructed
;
929 /* Setup properties */
930 obj_class
->get_property
= purple_buddy_presence_get_property
;
931 obj_class
->set_property
= purple_buddy_presence_set_property
;
933 bp_properties
[BUDPRES_PROP_BUDDY
] = g_param_spec_object("buddy", "Buddy",
934 "The buddy that this presence is of.", PURPLE_TYPE_BUDDY
,
935 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
|
936 G_PARAM_STATIC_STRINGS
);
938 g_object_class_install_properties(obj_class
, BUDPRES_PROP_LAST
,
943 purple_buddy_presence_init(PurpleBuddyPresence
*presence
)
947 PurpleBuddyPresence
*
948 purple_buddy_presence_new(PurpleBuddy
*buddy
)
950 g_return_val_if_fail(PURPLE_IS_BUDDY(buddy
), NULL
);
952 return g_object_new(PURPLE_TYPE_BUDDY_PRESENCE
,