Rename presence.[ch] to purplepresence.[ch], fix some docs, and other tweaks.
Testing Done:
Build, ran, and tested a bonjour account.
Reviewed at https://reviews.imfreedom.org/r/185/
--- a/doc/reference/libpurple/libpurple-docs.xml Sun Nov 01 02:42:18 2020 -0600
+++ b/doc/reference/libpurple/libpurple-docs.xml Sun Nov 01 03:33:09 2020 -0600
@@ -59,7 +59,6 @@
<xi:include href="xml/plugins.xml" />
<xi:include href="xml/prefs.xml" />
<xi:include href="xml/pluginpref.xml" />
- <xi:include href="xml/presence.xml" />
<xi:include href="xml/protocol.xml" />
<xi:include href="xml/protocols.xml" />
<xi:include href="xml/proxy.xml" />
@@ -73,6 +72,7 @@
<xi:include href="xml/purpleimconversation.xml" />
<xi:include href="xml/purplekeyvaluepair.xml" />
<xi:include href="xml/purplemarkup.xml" />
+ <xi:include href="xml/purplepresence.xml" /> <xi:include href="xml/purpleprotocolfactory.xml" />
<xi:include href="xml/purpleprotocolim.xml" />
<xi:include href="xml/purpleprotocolmedia.xml" />
--- a/libpurple/buddy.h Sun Nov 01 02:42:18 2020 -0600
+++ b/libpurple/buddy.h Sun Nov 01 03:33:09 2020 -0600
@@ -50,7 +50,7 @@
+#include "purplepresence.h" #define PURPLE_BUDDY_IS_ONLINE(b) \
--- a/libpurple/group.h Sun Nov 01 02:42:18 2020 -0600
+++ b/libpurple/group.h Sun Nov 01 03:33:09 2020 -0600
@@ -47,7 +47,6 @@
/**************************************************************************/
--- a/libpurple/meson.build Sun Nov 01 02:42:18 2020 -0600
+++ b/libpurple/meson.build Sun Nov 01 03:33:09 2020 -0600
@@ -43,7 +43,6 @@
@@ -58,6 +57,7 @@
'purpleimconversation.c',
'purpleprotocolfactory.c',
@@ -128,7 +128,6 @@
@@ -143,6 +142,7 @@
'purpleprotocolfactory.h',
--- a/libpurple/presence.c Sun Nov 01 02:42:18 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,464 +0,0 @@
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
-#include <glib/gi18n-lib.h>
-#include "purpleprivate.h"
- GHashTable *status_table;
- PurpleStatus *active_status;
-} PurplePresencePrivate;
-static GParamSpec *properties[N_PROPERTIES];
-G_DEFINE_TYPE_WITH_PRIVATE(PurplePresence, purple_presence, G_TYPE_OBJECT)
-/******************************************************************************
- *****************************************************************************/
-purple_presence_set_active_status(PurplePresence *presence,
- PurplePresencePrivate *priv = NULL;
- priv = purple_presence_get_instance_private(presence);
- if(g_set_object(&priv->active_status, status)) {
- g_object_notify_by_pspec(G_OBJECT(presence),
- properties[PROP_ACTIVE_STATUS]);
-/******************************************************************************
- * GObject Implementation
- *****************************************************************************/
-purple_presence_set_property(GObject *obj, guint param_id, const GValue *value,
- PurplePresence *presence = PURPLE_PRESENCE(obj);
- purple_presence_set_idle(presence, g_value_get_boolean(value), 0);
- purple_presence_set_idle(presence, TRUE, g_value_get_int(value));
-#elif SIZEOF_TIME_T == 8
- purple_presence_set_idle(presence, TRUE, g_value_get_int64(value));
-#error Unknown size of time_t
- purple_presence_set_login_time(presence, g_value_get_int(value));
-#elif SIZEOF_TIME_T == 8
- purple_presence_set_login_time(presence, g_value_get_int64(value));
-#error Unknown size of time_t
- case PROP_ACTIVE_STATUS:
- purple_presence_set_active_status(presence,
- g_value_get_object(value));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-/* Get method for GObject properties */
-purple_presence_get_property(GObject *obj, guint param_id, GValue *value,
- PurplePresence *presence = PURPLE_PRESENCE(obj);
- g_value_set_boolean(value, purple_presence_is_idle(presence));
- g_value_set_int(value, purple_presence_get_idle_time(presence));
-#elif SIZEOF_TIME_T == 8
- g_value_set_int64(value, purple_presence_get_idle_time(presence));
-#error Unknown size of time_t
- g_value_set_int(value, purple_presence_get_login_time(presence));
-#elif SIZEOF_TIME_T == 8
- g_value_set_int64(value, purple_presence_get_login_time(presence));
-#error Unknown size of time_t
- case PROP_ACTIVE_STATUS:
- g_value_set_object(value, purple_presence_get_active_status(presence));
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-purple_presence_init(PurplePresence *presence) {
- PurplePresencePrivate *priv = NULL;
- priv = purple_presence_get_instance_private(presence);
- priv->status_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-purple_presence_finalize(GObject *obj)
- PurplePresencePrivate *priv = NULL;
- priv = purple_presence_get_instance_private(PURPLE_PRESENCE(obj));
- g_hash_table_destroy(priv->status_table);
- g_clear_object(&priv->active_status);
- G_OBJECT_CLASS(purple_presence_parent_class)->finalize(obj);
-/* Class initializer function */
-static void purple_presence_class_init(PurplePresenceClass *klass)
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- obj_class->get_property = purple_presence_get_property;
- obj_class->set_property = purple_presence_set_property;
- obj_class->finalize = purple_presence_finalize;
- properties[PROP_IDLE] = g_param_spec_boolean("idle", "Idle",
- "Whether the presence is in idle state.", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_IDLE_TIME] =
-#elif SIZEOF_TIME_T == 8
-#error Unknown size of time_t
- ("idle-time", "Idle time",
- "The idle time of the presence",
-#elif SIZEOF_TIME_T == 8
- G_MININT64, G_MAXINT64, 0,
-#error Unknown size of time_t
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_LOGIN_TIME] =
-#elif SIZEOF_TIME_T == 8
-#error Unknown size of time_t
- ("login-time", "Login time",
- "The login time of the presence.",
-#elif SIZEOF_TIME_T == 8
- G_MININT64, G_MAXINT64, 0,
-#error Unknown size of time_t
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_ACTIVE_STATUS] = g_param_spec_object("active-status",
- "The active status for the presence.", PURPLE_TYPE_STATUS,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
-/******************************************************************************
- *****************************************************************************/
-purple_presence_set_status_active(PurplePresence *presence,
- const gchar *status_id, gboolean active)
- g_return_if_fail(PURPLE_IS_PRESENCE(presence));
- g_return_if_fail(status_id != NULL);
- status = purple_presence_get_status(presence, status_id);
- g_return_if_fail(PURPLE_IS_STATUS(status));
- /* TODO: Should we do the following? */
- /* g_return_if_fail(active == status->active); */
- if (purple_status_is_exclusive(status))
- purple_debug_warning("presence",
- "Attempted to set a non-independent status "
- "(%s) inactive. Only independent statuses "
- "can be specifically marked inactive.",
- purple_status_set_active(status, active);
-purple_presence_switch_status(PurplePresence *presence, const gchar *status_id)
- purple_presence_set_status_active(presence, status_id, TRUE);
-purple_presence_set_idle(PurplePresence *presence, gboolean idle,
- PurplePresencePrivate *priv = NULL;
- PurplePresenceClass *klass = NULL;
- g_return_if_fail(PURPLE_IS_PRESENCE(presence));
- priv = purple_presence_get_instance_private(presence);
- klass = PURPLE_PRESENCE_GET_CLASS(presence);
- if (priv->idle == idle && priv->idle_time == idle_time)
- priv->idle_time = (idle ? idle_time : 0);
- obj = G_OBJECT(presence);
- g_object_freeze_notify(obj);
- g_object_notify_by_pspec(obj, properties[PROP_IDLE]);
- g_object_notify_by_pspec(obj, properties[PROP_IDLE_TIME]);
- g_object_thaw_notify(obj);
- if (klass->update_idle)
- klass->update_idle(presence, old_idle);
-purple_presence_set_login_time(PurplePresence *presence, time_t login_time) {
- PurplePresencePrivate *priv = NULL;
- g_return_if_fail(PURPLE_IS_PRESENCE(presence));
- priv = purple_presence_get_instance_private(presence);
- if (priv->login_time == login_time)
- priv->login_time = login_time;
- g_object_notify_by_pspec(G_OBJECT(presence),
- properties[PROP_LOGIN_TIME]);
-purple_presence_get_statuses(PurplePresence *presence) {
- PurplePresenceClass *klass = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL);
- klass = PURPLE_PRESENCE_GET_CLASS(presence);
- if(klass && klass->get_statuses) {
- return klass->get_statuses(presence);
-purple_presence_get_status(PurplePresence *presence, const gchar *status_id) {
- PurplePresencePrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL);
- g_return_val_if_fail(status_id != NULL, NULL);
- priv = purple_presence_get_instance_private(presence);
- /* What's the purpose of this hash table? */
- status = (PurpleStatus *)g_hash_table_lookup(priv->status_table,
- for (l = purple_presence_get_statuses(presence);
- l != NULL && status == NULL; l = l->next)
- PurpleStatus *temp_status = l->data;
- if (purple_strequal(status_id, purple_status_get_id(temp_status)))
- g_hash_table_insert(priv->status_table,
- g_strdup(purple_status_get_id(status)), status);
-purple_presence_get_active_status(PurplePresence *presence) {
- PurplePresencePrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL);
- priv = purple_presence_get_instance_private(presence);
- return priv->active_status;
-purple_presence_is_available(PurplePresence *presence) {
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE);
- status = purple_presence_get_active_status(presence);
- return ((status != NULL && purple_status_is_available(status)) &&
- !purple_presence_is_idle(presence));
-purple_presence_is_online(PurplePresence *presence) {
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE);
- if ((status = purple_presence_get_active_status(presence)) == NULL)
- return purple_status_is_online(status);
-purple_presence_is_status_active(PurplePresence *presence,
- const gchar *status_id)
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE);
- g_return_val_if_fail(status_id != NULL, FALSE);
- status = purple_presence_get_status(presence, status_id);
- return (status != NULL && purple_status_is_active(status));
-purple_presence_is_status_primitive_active(PurplePresence *presence,
- PurpleStatusPrimitive primitive)
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE);
- g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, FALSE);
- for (l = purple_presence_get_statuses(presence);
- l != NULL; l = l->next)
- PurpleStatus *temp_status = l->data;
- PurpleStatusType *type = purple_status_get_status_type(temp_status);
- if (purple_status_type_get_primitive(type) == primitive &&
- purple_status_is_active(temp_status))
-purple_presence_is_idle(PurplePresence *presence) {
- PurplePresencePrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE);
- priv = purple_presence_get_instance_private(presence);
- return purple_presence_is_online(presence) && priv->idle;
-purple_presence_get_idle_time(PurplePresence *presence) {
- PurplePresencePrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), 0);
- priv = purple_presence_get_instance_private(presence);
- return priv->idle_time;
-purple_presence_get_login_time(PurplePresence *presence) {
- PurplePresencePrivate *priv = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), 0);
- priv = purple_presence_get_instance_private(presence);
- return purple_presence_is_online(presence) ? priv->login_time : 0;
--- a/libpurple/presence.h Sun Nov 01 02:42:18 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <https://www.gnu.org/licenses/>.
-#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
-# error "only <purple.h> may be included directly"
-#ifndef PURPLE_PRESENCE_H
-#define PURPLE_PRESENCE_H
- * @section_id: libpurple-presence
- * @short_description: <filename>presence.h</filename>
- * @title: Presence Objects API
- * This file contains the presence base type, account presence, and buddy
- * A PurplePresence is like a collection of PurpleStatuses (plus some
- * other random info). For any buddy, or for any one of your accounts,
- * or for any person with which you're chatting, you may know various
- * amounts of information. This information is all contained in
- * one PurplePresence. If one of your buddies is away and idle,
- * then the presence contains the PurpleStatus for their awayness,
- * and it contains their current idle time. PurplePresences are
- * never saved to disk. The information they contain is only relevant
- * for the current PurpleSession.
- * Note: When a presence is destroyed with the last g_object_unref(), all
- * statuses added to this list will be destroyed along with the presence.
-typedef struct _PurplePresence PurplePresence;
- * @update_idle: Updates the logs and the UI when the idle state or time of the
- * Base class for all #PurplePresence's
-struct _PurplePresenceClass {
- void (*update_idle)(PurplePresence *presence, gboolean old_idle);
- GList *(*get_statuses)(PurplePresence *presence);
- * PURPLE_TYPE_PRESENCE:
- * The standard _get_type macro for #PurplePresence.
-#define PURPLE_TYPE_PRESENCE purple_presence_get_type()
- * purple_presence_get_type:
- * Returns: The #GType for the #PurplePresence object.
-G_DECLARE_DERIVABLE_TYPE(PurplePresence, purple_presence, PURPLE, PRESENCE,
- * purple_presence_set_status_active:
- * @presence: The presence.
- * @status_id: The ID of the status.
- * @active: The active state.
- * Sets the active state of a status in a presence.
- * Only independent statuses can be set unactive. Normal statuses can only
- * be set active, so if you wish to disable a status, set another
- * non-independent status to active, or use purple_presence_switch_status().
-void purple_presence_set_status_active(PurplePresence *presence, const gchar *status_id, gboolean active);
- * purple_presence_switch_status:
- * @presence: The presence.
- * @status_id: The status ID to switch to.
- * Switches the active status in a presence.
- * This is similar to purple_presence_set_status_active(), except it won't
- * activate independent statuses.
-void purple_presence_switch_status(PurplePresence *presence, const gchar *status_id);
- * purple_presence_set_idle:
- * @presence: The presence.
- * @idle: The idle state.
- * @idle_time: The idle time, if @idle is TRUE. This
- * is the time at which the user became idle,
- * in seconds since the epoch. If this value is
- * unknown then 0 should be used.
- * Sets the idle state and time on a presence.
-void purple_presence_set_idle(PurplePresence *presence, gboolean idle, time_t idle_time);
- * purple_presence_set_login_time:
- * @presence: The presence.
- * @login_time: The login time.
- * Sets the login time on a presence.
-void purple_presence_set_login_time(PurplePresence *presence, time_t login_time);
- * purple_presence_get_statuses:
- * @presence: The presence.
- * Returns all the statuses in a presence.
- * Returns: (element-type PurpleStatus) (transfer none): The statuses.
-GList *purple_presence_get_statuses(PurplePresence *presence);
- * purple_presence_get_status:
- * @presence: The presence.
- * @status_id: The ID of the status.
- * Returns the status with the specified ID from a presence.
- * Returns: (transfer none): The status if found, or %NULL.
-PurpleStatus *purple_presence_get_status(PurplePresence *presence, const gchar *status_id);
- * purple_presence_get_active_status:
- * @presence: The presence.
- * Returns the active exclusive status from a presence.
- * Returns: (transfer none): The active exclusive status.
-PurpleStatus *purple_presence_get_active_status(PurplePresence *presence);
- * purple_presence_is_available:
- * @presence: The presence.
- * Returns whether or not a presence is available.
- * Available presences are online and possibly invisible, but not away or idle.
- * Returns: TRUE if the presence is available, or FALSE otherwise.
-gboolean purple_presence_is_available(PurplePresence *presence);
- * purple_presence_is_online:
- * @presence: The presence.
- * Returns whether or not a presence is online.
- * Returns: TRUE if the presence is online, or FALSE otherwise.
-gboolean purple_presence_is_online(PurplePresence *presence);
- * purple_presence_is_status_active:
- * @presence: The presence.
- * @status_id: The ID of the status.
- * Returns whether or not a status in a presence is active.
- * A status is active if itself or any of its sub-statuses are active.
- * Returns: TRUE if the status is active, or FALSE.
-gboolean purple_presence_is_status_active(PurplePresence *presence, const gchar *status_id);
- * purple_presence_is_status_primitive_active:
- * @presence: The presence.
- * @primitive: The status primitive.
- * Returns whether or not a status with the specified primitive type
- * in a presence is active.
- * A status is active if itself or any of its sub-statuses are active.
- * Returns: TRUE if the status is active, or FALSE.
-gboolean purple_presence_is_status_primitive_active(PurplePresence *presence, PurpleStatusPrimitive primitive);
- * purple_presence_is_idle:
- * @presence: The presence.
- * Returns whether or not a presence is idle.
- * Returns: TRUE if the presence is idle, or FALSE otherwise.
- * If the presence is offline (purple_presence_is_online()
- * returns FALSE) then FALSE is returned.
-gboolean purple_presence_is_idle(PurplePresence *presence);
- * purple_presence_get_idle_time:
- * @presence: The presence.
- * Returns the presence's idle time.
- * Returns: The presence's idle time.
-time_t purple_presence_get_idle_time(PurplePresence *presence);
- * purple_presence_get_login_time:
- * @presence: The presence.
- * Returns the presence's login time.
- * Returns: The presence's login time.
-time_t purple_presence_get_login_time(PurplePresence *presence);
-#endif /* PURPLE_PRESENCE_H */
--- a/libpurple/purpleaccountpresence.h Sun Nov 01 02:42:18 2020 -0600
+++ b/libpurple/purpleaccountpresence.h Sun Nov 01 03:33:09 2020 -0600
@@ -31,7 +31,7 @@
+#include "purplepresence.h" --- a/libpurple/purplebuddypresence.h Sun Nov 01 02:42:18 2020 -0600
+++ b/libpurple/purplebuddypresence.h Sun Nov 01 03:33:09 2020 -0600
@@ -31,7 +31,7 @@
+#include "purplepresence.h" --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplepresence.c Sun Nov 01 03:33:09 2020 -0600
@@ -0,0 +1,493 @@
+ * Copyright (C) Pidgin Developers <devel@pidgin.im> + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses/>. +#include <glib/gi18n-lib.h> +#include "purplepresence.h" +#include "purpleprivate.h" + GHashTable *status_table; + PurpleStatus *active_status; +} PurplePresencePrivate; +static GParamSpec *properties[N_PROPERTIES]; +G_DEFINE_TYPE_WITH_PRIVATE(PurplePresence, purple_presence, G_TYPE_OBJECT) +/****************************************************************************** + *****************************************************************************/ +purple_presence_set_active_status(PurplePresence *presence, + PurplePresencePrivate *priv = NULL; + priv = purple_presence_get_instance_private(presence); + if(g_set_object(&priv->active_status, status)) { + g_object_notify_by_pspec(G_OBJECT(presence), + properties[PROP_ACTIVE_STATUS]); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +purple_presence_set_property(GObject *obj, guint param_id, const GValue *value, + PurplePresence *presence = PURPLE_PRESENCE(obj); + purple_presence_set_idle(presence, g_value_get_boolean(value), 0); + purple_presence_set_idle(presence, TRUE, g_value_get_int(value)); +#elif SIZEOF_TIME_T == 8 + purple_presence_set_idle(presence, TRUE, g_value_get_int64(value)); +#error Unknown size of time_t + purple_presence_set_login_time(presence, g_value_get_int(value)); +#elif SIZEOF_TIME_T == 8 + purple_presence_set_login_time(presence, g_value_get_int64(value)); +#error Unknown size of time_t + case PROP_ACTIVE_STATUS: + purple_presence_set_active_status(presence, + g_value_get_object(value)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_presence_get_property(GObject *obj, guint param_id, GValue *value, + PurplePresence *presence = PURPLE_PRESENCE(obj); + g_value_set_boolean(value, purple_presence_is_idle(presence)); + g_value_set_int(value, purple_presence_get_idle_time(presence)); +#elif SIZEOF_TIME_T == 8 + g_value_set_int64(value, purple_presence_get_idle_time(presence)); +#error Unknown size of time_t + g_value_set_int(value, purple_presence_get_login_time(presence)); +#elif SIZEOF_TIME_T == 8 + g_value_set_int64(value, purple_presence_get_login_time(presence)); +#error Unknown size of time_t + case PROP_ACTIVE_STATUS: + g_value_set_object(value, purple_presence_get_active_status(presence)); + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); +purple_presence_init(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + priv = purple_presence_get_instance_private(presence); + priv->status_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, +purple_presence_finalize(GObject *obj) { + PurplePresencePrivate *priv = NULL; + priv = purple_presence_get_instance_private(PURPLE_PRESENCE(obj)); + g_hash_table_destroy(priv->status_table); + g_clear_object(&priv->active_status); + G_OBJECT_CLASS(purple_presence_parent_class)->finalize(obj); +purple_presence_class_init(PurplePresenceClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + obj_class->get_property = purple_presence_get_property; + obj_class->set_property = purple_presence_set_property; + obj_class->finalize = purple_presence_finalize; + * Whether or not the presence is in an idle state. + properties[PROP_IDLE] = g_param_spec_boolean("idle", "Idle", + "Whether the presence is in idle state.", FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurplePresence:idle-time: + * The time when the presence went idle. + properties[PROP_IDLE_TIME] = +#elif SIZEOF_TIME_T == 8 +#error Unknown size of time_t + ("idle-time", "Idle time", + "The idle time of the presence", +#elif SIZEOF_TIME_T == 8 + G_MININT64, G_MAXINT64, 0, +#error Unknown size of time_t + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurplePresence:login-time: + * The login-time of the presence. + properties[PROP_LOGIN_TIME] = +#elif SIZEOF_TIME_T == 8 +#error Unknown size of time_t + ("login-time", "Login time", + "The login time of the presence.", +#elif SIZEOF_TIME_T == 8 + G_MININT64, G_MAXINT64, 0, +#error Unknown size of time_t + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurplePresence:active-status: + * The currently active status of the presence. + properties[PROP_ACTIVE_STATUS] = g_param_spec_object("active-status", + "The active status for the presence.", PURPLE_TYPE_STATUS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +/****************************************************************************** + *****************************************************************************/ +purple_presence_set_status_active(PurplePresence *presence, + const gchar *status_id, gboolean active) + PurpleStatus *status = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + g_return_if_fail(status_id != NULL); + status = purple_presence_get_status(presence, status_id); + g_return_if_fail(PURPLE_IS_STATUS(status)); + /* TODO: Should we do the following? */ + /* g_return_if_fail(active == status->active); */ + if(purple_status_is_exclusive(status)) { + purple_debug_warning("presence", + "Attempted to set a non-independent status " + "(%s) inactive. Only independent statuses " + "can be specifically marked inactive.", + purple_status_set_active(status, active); +purple_presence_switch_status(PurplePresence *presence, const gchar *status_id) + purple_presence_set_status_active(presence, status_id, TRUE); +purple_presence_set_idle(PurplePresence *presence, gboolean idle, + PurplePresencePrivate *priv = NULL; + PurplePresenceClass *klass = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + priv = purple_presence_get_instance_private(presence); + klass = PURPLE_PRESENCE_GET_CLASS(presence); + if (priv->idle == idle && priv->idle_time == idle_time) { + priv->idle_time = (idle ? idle_time : 0); + obj = G_OBJECT(presence); + g_object_freeze_notify(obj); + g_object_notify_by_pspec(obj, properties[PROP_IDLE]); + g_object_notify_by_pspec(obj, properties[PROP_IDLE_TIME]); + g_object_thaw_notify(obj); + if(klass->update_idle) { + klass->update_idle(presence, old_idle); +purple_presence_set_login_time(PurplePresence *presence, time_t login_time) { + PurplePresencePrivate *priv = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + priv = purple_presence_get_instance_private(presence); + if(priv->login_time == login_time) { + priv->login_time = login_time; + g_object_notify_by_pspec(G_OBJECT(presence), + properties[PROP_LOGIN_TIME]); +purple_presence_get_statuses(PurplePresence *presence) { + PurplePresenceClass *klass = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL); + klass = PURPLE_PRESENCE_GET_CLASS(presence); + if(klass && klass->get_statuses) { + return klass->get_statuses(presence); +purple_presence_get_status(PurplePresence *presence, const gchar *status_id) { + PurplePresencePrivate *priv = NULL; + PurpleStatus *status = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL); + g_return_val_if_fail(status_id != NULL, NULL); + priv = purple_presence_get_instance_private(presence); + /* What's the purpose of this hash table? */ + status = (PurpleStatus *)g_hash_table_lookup(priv->status_table, + for(l = purple_presence_get_statuses(presence); + l != NULL && status == NULL; l = l->next) + PurpleStatus *temp_status = l->data; + if (purple_strequal(status_id, purple_status_get_id(temp_status))) { + g_hash_table_insert(priv->status_table, + g_strdup(purple_status_get_id(status)), status); +purple_presence_get_active_status(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL); + priv = purple_presence_get_instance_private(presence); + return priv->active_status; +purple_presence_is_available(PurplePresence *presence) { + PurpleStatus *status = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + status = purple_presence_get_active_status(presence); + return ((status != NULL && purple_status_is_available(status)) && + !purple_presence_is_idle(presence)); +purple_presence_is_online(PurplePresence *presence) { + PurpleStatus *status = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + if((status = purple_presence_get_active_status(presence)) == NULL) { + return purple_status_is_online(status); +purple_presence_is_status_active(PurplePresence *presence, + const gchar *status_id) + PurpleStatus *status = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + g_return_val_if_fail(status_id != NULL, FALSE); + status = purple_presence_get_status(presence, status_id); + return (status != NULL && purple_status_is_active(status)); +purple_presence_is_status_primitive_active(PurplePresence *presence, + PurpleStatusPrimitive primitive) + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, FALSE); + for(l = purple_presence_get_statuses(presence); l != NULL; l = l->next) { + PurpleStatus *temp_status = l->data; + PurpleStatusType *type = purple_status_get_status_type(temp_status); + if(purple_status_type_get_primitive(type) == primitive && + purple_status_is_active(temp_status)) +purple_presence_is_idle(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + if(!purple_presence_is_online(presence)) { + priv = purple_presence_get_instance_private(presence); +purple_presence_get_idle_time(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), 0); + priv = purple_presence_get_instance_private(presence); + return priv->idle_time; +purple_presence_get_login_time(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), 0); + priv = purple_presence_get_instance_private(presence); + return purple_presence_is_online(presence) ? priv->login_time : 0; --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplepresence.h Sun Nov 01 03:33:09 2020 -0600
@@ -0,0 +1,257 @@
+ * Copyright (C) Pidgin Developers <devel@pidgin.im> + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses/>. +#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) +# error "only <purple.h> may be included directly" +#ifndef PURPLE_PRESENCE_H +#define PURPLE_PRESENCE_H + * SECTION:purplepresence + * @section_id: libpurple-purplepresence + * @title: Presence Object API + * This file contains the base #PurplePresence type which is used by + * #PurpleAccountPresence and #PurpleBuddyPresence. + * A PurplePresence is like a collection of PurpleStatuses (plus some other + * random info). For any buddy, or for any one of your accounts, or for any + * person with which you're chatting, you may know various amounts of + * information. This information is all contained in one PurplePresence. If + * one of your buddies is away and idle, then the presence contains the + * #PurpleStatus for their awayness, and it contains their current idle time. + * #PurplePresence's are never saved to disk. The information they contain is + * only relevant for the current Purple session. + * Note: When a presence is destroyed with the last g_object_unref(), all + * statuses added to this list will be destroyed along with the presence. +typedef struct _PurplePresence PurplePresence; + * @update_idle: Updates the logs and the UI when the idle state or time of the + * The base class for all #PurplePresence's. +struct _PurplePresenceClass { + void (*update_idle)(PurplePresence *presence, gboolean old_idle); + GList *(*get_statuses)(PurplePresence *presence); + * PURPLE_TYPE_PRESENCE: + * The standard _get_type macro for #PurplePresence. +#define PURPLE_TYPE_PRESENCE purple_presence_get_type() + * purple_presence_get_type: + * Returns: The #GType for the #PurplePresence object. +G_DECLARE_DERIVABLE_TYPE(PurplePresence, purple_presence, PURPLE, PRESENCE, + * purple_presence_set_status_active: + * @presence: The #PurplePresence instance. + * @status_id: The ID of the status. + * @active: The active state. + * Sets the active state of a status in a presence. + * Only independent statuses can be set inactive. Normal statuses can only + * be set active, so if you wish to disable a status, set another + * non-independent status to active, or use purple_presence_switch_status(). +void purple_presence_set_status_active(PurplePresence *presence, const gchar *status_id, gboolean active); + * purple_presence_switch_status: + * @presence: The #PurplePresence instace. + * @status_id: The status ID to switch to. + * Switches the active status in a presence. + * This is similar to purple_presence_set_status_active(), except it won't + * activate independent statuses. +void purple_presence_switch_status(PurplePresence *presence, const gchar *status_id); + * purple_presence_set_idle: + * @presence: The #PurplePresence instance. + * @idle: The idle state. + * @idle_time: The idle time, if @idle is %TRUE. This is the time at which the + * user became idle, in seconds since the epoch. If this value is + * unknown then 0 should be used. + * Sets the idle state and time of @presence. +void purple_presence_set_idle(PurplePresence *presence, gboolean idle, time_t idle_time); + * purple_presence_set_login_time: + * @presence: The #PurplePresence instance. + * @login_time: The login time. + * Sets the login time on a presence. +void purple_presence_set_login_time(PurplePresence *presence, time_t login_time); + * purple_presence_get_statuses: + * @presence: The #PurplePresence instance. + * Gets a list of all the statuses in @presence. + * Returns: (element-type PurpleStatus) (transfer none): The statuses. +GList *purple_presence_get_statuses(PurplePresence *presence); + * purple_presence_get_status: + * @presence: The #PurplePresence instance. + * @status_id: The ID of the status. + * Gets the status with the specified ID from @presence. + * Returns: (transfer none): The #PurpleStatus if found, or %NULL. +PurpleStatus *purple_presence_get_status(PurplePresence *presence, const gchar *status_id); + * purple_presence_get_active_status: + * @presence: The #PurplePresence instance. + * Gets the active exclusive status from @presence. + * Returns: (transfer none): The active exclusive status. +PurpleStatus *purple_presence_get_active_status(PurplePresence *presence); + * purple_presence_is_available: + * @presence: The #PurplePresence instance. + * Gets whether or not @presence is available. + * Available presences are online and possibly invisible, but not away or idle. + * Returns: %TRUE if the presence is available, or %FALSE otherwise. +gboolean purple_presence_is_available(PurplePresence *presence); + * purple_presence_is_online: + * @presence: The #PurplePresence instance. + * Gets whether or not @presence is online. + * Returns: %TRUE if the presence is online, or %FALSE otherwise. +gboolean purple_presence_is_online(PurplePresence *presence); + * purple_presence_is_status_active: + * @presence: The #PurplePresence instance. + * @status_id: The ID of the status. + * Gets whether or not a status in @presence is active. + * A status is active if itself or any of its sub-statuses are active. + * Returns: %TRUE if the status is active, or %FALSE. +gboolean purple_presence_is_status_active(PurplePresence *presence, const gchar *status_id); + * purple_presence_is_status_primitive_active: + * @presence: The #PurplePresence instance. + * @primitive: The status primitive. + * Gets whether or not a status with the specified primitive type in @presence + * A status is active if itself or any of its sub-statuses are active. + * Returns: %TRUE if the status is active, or %FALSE. +gboolean purple_presence_is_status_primitive_active(PurplePresence *presence, PurpleStatusPrimitive primitive); + * purple_presence_is_idle: + * @presence: The #PurplePresence instance. + * Gets whether or not @presence is idle. + * Returns: %TRUE if the presence is idle, or %FALSE otherwise. If the + * presence is offline (purple_presence_is_online() returns %FALSE) + * then %FALSE is returned. +gboolean purple_presence_is_idle(PurplePresence *presence); + * purple_presence_get_idle_time: + * @presence: The #PurplePresence instance. + * Gets the idle time of @presence. + * Returns: The idle time of @presence. +time_t purple_presence_get_idle_time(PurplePresence *presence); + * purple_presence_get_login_time: + * @presence: The #PurplePresence instance. + * Gets the login time of @presence. + * Returns: The login time of @presence. +time_t purple_presence_get_login_time(PurplePresence *presence); +#endif /* PURPLE_PRESENCE_H */ --- a/libpurple/status.h Sun Nov 01 02:42:18 2020 -0600
+++ b/libpurple/status.h Sun Nov 01 03:33:09 2020 -0600
@@ -119,7 +119,7 @@
PURPLE_STATUS_NUM_PRIMITIVES, /*< skip >*/
+#include "purplepresence.h" --- a/po/POTFILES.in Sun Nov 01 02:42:18 2020 -0600
+++ b/po/POTFILES.in Sun Nov 01 03:33:09 2020 -0600
@@ -90,7 +90,6 @@
libpurple/plugins/test-request-input.c
libpurple/protocols/bonjour/bonjour.c
libpurple/protocols/bonjour/bonjour_ft.c
@@ -270,6 +269,7 @@
libpurple/purplecredentialprovider.c
libpurple/purpleimconversation.c
+libpurple/purplepresence.c libpurple/purpleprotocolim.c
libpurple/purpleprotocolmedia.c
libpurple/purpleprotocolprivacy.c