pidgin/pidgin

Parents 98384d15c7a0
Children 9616360d5943
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 "contact.h"
#include "group.h"
#include "media.h"
-#include "presence.h"
+#include "purplepresence.h"
#include "status.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 @@
#include "account.h"
#include "blistnode.h"
#include "buddyicon.h"
-#include "presence.h"
#include "status.h"
/**************************************************************************/
--- 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 @@
'pluginpref.c',
'pounce.c',
'prefs.c',
- 'presence.c',
'proxy.c',
'protocol.c',
'protocols.c',
@@ -58,6 +57,7 @@
'purpleimconversation.c',
'purplekeyvaluepair.c',
'purplemarkup.c',
+ 'purplepresence.c',
'purpleprotocolfactory.c',
'purpleprotocolim.c',
'purpleprotocolmedia.c',
@@ -128,7 +128,6 @@
'pluginpref.h',
'pounce.h',
'prefs.h',
- 'presence.h',
'proxy.h',
'protocol.h',
'protocols.h',
@@ -143,6 +142,7 @@
'purpleattachment.h',
'purplekeyvaluepair.h',
'purplemarkup.h',
+ 'purplepresence.h',
'purpleprotocolfactory.h',
'purpleprotocolim.h',
'purpleprotocolmedia.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
- *
- * 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
- * source distribution.
- *
- * 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 "internal.h"
-#include "debug.h"
-#include "presence.h"
-#include "purpleprivate.h"
-
-typedef struct {
- gboolean idle;
- time_t idle_time;
- time_t login_time;
-
- GHashTable *status_table;
-
- PurpleStatus *active_status;
-} PurplePresencePrivate;
-
-enum {
- PROP_0,
- PROP_IDLE,
- PROP_IDLE_TIME,
- PROP_LOGIN_TIME,
- PROP_ACTIVE_STATUS,
- N_PROPERTIES
-};
-static GParamSpec *properties[N_PROPERTIES];
-
-G_DEFINE_TYPE_WITH_PRIVATE(PurplePresence, purple_presence, G_TYPE_OBJECT)
-
-/******************************************************************************
- * Helpers
- *****************************************************************************/
-static void
-purple_presence_set_active_status(PurplePresence *presence,
- PurpleStatus *status)
-{
- 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
- *****************************************************************************/
-static void
-purple_presence_set_property(GObject *obj, guint param_id, const GValue *value,
- GParamSpec *pspec)
-{
- PurplePresence *presence = PURPLE_PRESENCE(obj);
-
- switch (param_id) {
- case PROP_IDLE:
- purple_presence_set_idle(presence, g_value_get_boolean(value), 0);
- break;
- case PROP_IDLE_TIME:
-#if SIZEOF_TIME_T == 4
- 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));
-#else
-#error Unknown size of time_t
-#endif
- break;
- case PROP_LOGIN_TIME:
-#if SIZEOF_TIME_T == 4
- 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));
-#else
-#error Unknown size of time_t
-#endif
- break;
- case PROP_ACTIVE_STATUS:
- purple_presence_set_active_status(presence,
- g_value_get_object(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-/* Get method for GObject properties */
-static void
-purple_presence_get_property(GObject *obj, guint param_id, GValue *value,
- GParamSpec *pspec)
-{
- PurplePresence *presence = PURPLE_PRESENCE(obj);
-
- switch (param_id) {
- case PROP_IDLE:
- g_value_set_boolean(value, purple_presence_is_idle(presence));
- break;
- case PROP_IDLE_TIME:
-#if SIZEOF_TIME_T == 4
- 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));
-#else
-#error Unknown size of time_t
-#endif
- break;
- case PROP_LOGIN_TIME:
-#if SIZEOF_TIME_T == 4
- 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));
-#else
-#error Unknown size of time_t
-#endif
- break;
- case PROP_ACTIVE_STATUS:
- g_value_set_object(value, purple_presence_get_active_status(presence));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
- break;
- }
-}
-
-static void
-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,
- NULL);
-}
-
-static void
-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] =
-#if SIZEOF_TIME_T == 4
- g_param_spec_int
-#elif SIZEOF_TIME_T == 8
- g_param_spec_int64
-#else
-#error Unknown size of time_t
-#endif
- ("idle-time", "Idle time",
- "The idle time of the presence",
-#if SIZEOF_TIME_T == 4
- G_MININT, G_MAXINT, 0,
-#elif SIZEOF_TIME_T == 8
- G_MININT64, G_MAXINT64, 0,
-#else
-#error Unknown size of time_t
-#endif
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_LOGIN_TIME] =
-#if SIZEOF_TIME_T == 4
- g_param_spec_int
-#elif SIZEOF_TIME_T == 8
- g_param_spec_int64
-#else
-#error Unknown size of time_t
-#endif
- ("login-time", "Login time",
- "The login time of the presence.",
-#if SIZEOF_TIME_T == 4
- G_MININT, G_MAXINT, 0,
-#elif SIZEOF_TIME_T == 8
- G_MININT64, G_MAXINT64, 0,
-#else
-#error Unknown size of time_t
-#endif
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_ACTIVE_STATUS] = g_param_spec_object("active-status",
- "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);
-}
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-void
-purple_presence_set_status_active(PurplePresence *presence,
- const gchar *status_id, gboolean active)
-{
- PurpleStatus *status;
-
- 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))
- {
- if (!active)
- {
- purple_debug_warning("presence",
- "Attempted to set a non-independent status "
- "(%s) inactive. Only independent statuses "
- "can be specifically marked inactive.",
- status_id);
- return;
- }
- }
-
- purple_status_set_active(status, active);
-}
-
-void
-purple_presence_switch_status(PurplePresence *presence, const gchar *status_id)
-{
- purple_presence_set_status_active(presence, status_id, TRUE);
-}
-
-void
-purple_presence_set_idle(PurplePresence *presence, gboolean idle,
- time_t idle_time)
-{
- PurplePresencePrivate *priv = NULL;
- PurplePresenceClass *klass = NULL;
- gboolean old_idle;
- GObject *obj;
-
- 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)
- return;
-
- old_idle = priv->idle;
- priv->idle = idle;
- 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);
-}
-
-void
-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)
- return;
-
- priv->login_time = login_time;
-
- g_object_notify_by_pspec(G_OBJECT(presence),
- properties[PROP_LOGIN_TIME]);
-}
-
-GList *
-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);
- }
-
- return NULL;
-}
-
-PurpleStatus *
-purple_presence_get_status(PurplePresence *presence, const gchar *status_id) {
- PurplePresencePrivate *priv = NULL;
- PurpleStatus *status;
- GList *l = 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,
- status_id);
-
- if (status == NULL) {
- 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)))
- status = temp_status;
- }
-
- if (status != NULL)
- g_hash_table_insert(priv->status_table,
- g_strdup(purple_status_get_id(status)), status);
- }
-
- return status;
-}
-
-PurpleStatus *
-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;
-}
-
-gboolean
-purple_presence_is_available(PurplePresence *presence) {
- PurpleStatus *status;
-
- 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));
-}
-
-gboolean
-purple_presence_is_online(PurplePresence *presence) {
- PurpleStatus *status;
-
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE);
-
- if ((status = purple_presence_get_active_status(presence)) == NULL)
- return FALSE;
-
- return purple_status_is_online(status);
-}
-
-gboolean
-purple_presence_is_status_active(PurplePresence *presence,
- const gchar *status_id)
-{
- PurpleStatus *status;
-
- 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));
-}
-
-gboolean
-purple_presence_is_status_primitive_active(PurplePresence *presence,
- PurpleStatusPrimitive primitive)
-{
- GList *l;
-
- 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))
- return TRUE;
- }
- return FALSE;
-}
-
-gboolean
-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;
-}
-
-time_t
-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;
-}
-
-time_t
-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
- *
- * 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
- * source distribution.
- *
- * 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"
-#endif
-
-#ifndef PURPLE_PRESENCE_H
-#define PURPLE_PRESENCE_H
-
-/**
- * SECTION:presence
- * @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
- * presence API.
- */
-
-/**
- * PurplePresence:
- *
- * 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;
-
-#include "buddylist.h"
-#include "status.h"
-
-/**
- * PurplePresenceClass:
- * @update_idle: Updates the logs and the UI when the idle state or time of the
- * presence changes.
- *
- * Base class for all #PurplePresence's
- */
-struct _PurplePresenceClass {
- /*< private >*/
- GObjectClass parent;
-
- /*< public >*/
- void (*update_idle)(PurplePresence *presence, gboolean old_idle);
- GList *(*get_statuses)(PurplePresence *presence);
-
- /*< private >*/
- gpointer reserved[4];
-};
-
-G_BEGIN_DECLS
-
-/**
- * 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,
- GObject)
-
-/**
- * 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);
-
-G_END_DECLS
-
-#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 "account.h"
-#include "presence.h"
+#include "purplepresence.h"
G_BEGIN_DECLS
--- 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 "buddylist.h"
-#include "presence.h"
+#include "purplepresence.h"
G_BEGIN_DECLS
--- /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 @@
+/*
+ * purple
+ * 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
+ * source distribution.
+ *
+ * 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 "internal.h"
+#include "debug.h"
+#include "purplepresence.h"
+#include "purpleprivate.h"
+
+typedef struct {
+ gboolean idle;
+ time_t idle_time;
+ time_t login_time;
+
+ GHashTable *status_table;
+
+ PurpleStatus *active_status;
+} PurplePresencePrivate;
+
+enum {
+ PROP_0,
+ PROP_IDLE,
+ PROP_IDLE_TIME,
+ PROP_LOGIN_TIME,
+ PROP_ACTIVE_STATUS,
+ N_PROPERTIES
+};
+static GParamSpec *properties[N_PROPERTIES];
+
+G_DEFINE_TYPE_WITH_PRIVATE(PurplePresence, purple_presence, G_TYPE_OBJECT)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_presence_set_active_status(PurplePresence *presence,
+ PurpleStatus *status)
+{
+ 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
+ *****************************************************************************/
+static void
+purple_presence_set_property(GObject *obj, guint param_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ PurplePresence *presence = PURPLE_PRESENCE(obj);
+
+ switch (param_id) {
+ case PROP_IDLE:
+ purple_presence_set_idle(presence, g_value_get_boolean(value), 0);
+ break;
+ case PROP_IDLE_TIME:
+#if SIZEOF_TIME_T == 4
+ 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));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PROP_LOGIN_TIME:
+#if SIZEOF_TIME_T == 4
+ 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));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PROP_ACTIVE_STATUS:
+ purple_presence_set_active_status(presence,
+ g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_presence_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurplePresence *presence = PURPLE_PRESENCE(obj);
+
+ switch (param_id) {
+ case PROP_IDLE:
+ g_value_set_boolean(value, purple_presence_is_idle(presence));
+ break;
+ case PROP_IDLE_TIME:
+#if SIZEOF_TIME_T == 4
+ 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));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PROP_LOGIN_TIME:
+#if SIZEOF_TIME_T == 4
+ 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));
+#else
+#error Unknown size of time_t
+#endif
+ break;
+ case PROP_ACTIVE_STATUS:
+ g_value_set_object(value, purple_presence_get_active_status(presence));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+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,
+ NULL);
+}
+
+static void
+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);
+}
+
+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;
+
+ /**
+ * PurplePresence:idle:
+ *
+ * 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] =
+#if SIZEOF_TIME_T == 4
+ g_param_spec_int
+#elif SIZEOF_TIME_T == 8
+ g_param_spec_int64
+#else
+#error Unknown size of time_t
+#endif
+ ("idle-time", "Idle time",
+ "The idle time of the presence",
+#if SIZEOF_TIME_T == 4
+ G_MININT, G_MAXINT, 0,
+#elif SIZEOF_TIME_T == 8
+ G_MININT64, G_MAXINT64, 0,
+#else
+#error Unknown size of time_t
+#endif
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurplePresence:login-time:
+ *
+ * The login-time of the presence.
+ */
+ properties[PROP_LOGIN_TIME] =
+#if SIZEOF_TIME_T == 4
+ g_param_spec_int
+#elif SIZEOF_TIME_T == 8
+ g_param_spec_int64
+#else
+#error Unknown size of time_t
+#endif
+ ("login-time", "Login time",
+ "The login time of the presence.",
+#if SIZEOF_TIME_T == 4
+ G_MININT, G_MAXINT, 0,
+#elif SIZEOF_TIME_T == 8
+ G_MININT64, G_MAXINT64, 0,
+#else
+#error Unknown size of time_t
+#endif
+ 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",
+ "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);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+void
+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)) {
+ if(!active) {
+ purple_debug_warning("presence",
+ "Attempted to set a non-independent status "
+ "(%s) inactive. Only independent statuses "
+ "can be specifically marked inactive.",
+ status_id);
+ return;
+ }
+ }
+
+ purple_status_set_active(status, active);
+}
+
+void
+purple_presence_switch_status(PurplePresence *presence, const gchar *status_id)
+{
+ purple_presence_set_status_active(presence, status_id, TRUE);
+}
+
+void
+purple_presence_set_idle(PurplePresence *presence, gboolean idle,
+ time_t idle_time)
+{
+ PurplePresencePrivate *priv = NULL;
+ PurplePresenceClass *klass = NULL;
+ gboolean old_idle;
+ GObject *obj = 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) {
+ return;
+ }
+
+ old_idle = priv->idle;
+ priv->idle = idle;
+ 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);
+ }
+}
+
+void
+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) {
+ return;
+ }
+
+ priv->login_time = login_time;
+
+ g_object_notify_by_pspec(G_OBJECT(presence),
+ properties[PROP_LOGIN_TIME]);
+}
+
+GList *
+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);
+ }
+
+ return NULL;
+}
+
+PurpleStatus *
+purple_presence_get_status(PurplePresence *presence, const gchar *status_id) {
+ PurplePresencePrivate *priv = NULL;
+ PurpleStatus *status = NULL;
+ GList *l = 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,
+ status_id);
+
+ if(status == NULL) {
+ 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))) {
+ status = temp_status;
+ }
+ }
+
+ if(status != NULL) {
+ g_hash_table_insert(priv->status_table,
+ g_strdup(purple_status_get_id(status)), status);
+ }
+ }
+
+ return status;
+}
+
+PurpleStatus *
+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;
+}
+
+gboolean
+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));
+}
+
+gboolean
+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 FALSE;
+ }
+
+ return purple_status_is_online(status);
+}
+
+gboolean
+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));
+}
+
+gboolean
+purple_presence_is_status_primitive_active(PurplePresence *presence,
+ PurpleStatusPrimitive primitive)
+{
+ GList *l = NULL;
+
+ 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))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+gboolean
+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)) {
+ return FALSE;
+ }
+
+ priv = purple_presence_get_instance_private(presence);
+
+ return priv->idle;
+}
+
+time_t
+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;
+}
+
+time_t
+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 @@
+/*
+ * purple
+ * 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
+ * source distribution.
+ *
+ * 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"
+#endif
+
+#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.
+ */
+
+/**
+ * PurplePresence:
+ *
+ * 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;
+
+#include "status.h"
+
+G_BEGIN_DECLS
+
+/**
+ * PurplePresenceClass:
+ * @update_idle: Updates the logs and the UI when the idle state or time of the
+ * presence changes.
+ *
+ * The base class for all #PurplePresence's.
+ */
+struct _PurplePresenceClass {
+ /*< private >*/
+ GObjectClass parent;
+
+ /*< public >*/
+ void (*update_idle)(PurplePresence *presence, gboolean old_idle);
+ GList *(*get_statuses)(PurplePresence *presence);
+
+ /*< private >*/
+ gpointer reserved[4];
+};
+
+/**
+ * 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,
+ GObject)
+
+/**
+ * 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
+ * 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 #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);
+
+G_END_DECLS
+
+#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 >*/
} PurpleStatusPrimitive;
-#include "presence.h"
+#include "purplepresence.h"
/**
* PURPLE_TUNE_ALBUM:
--- 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/pounce.c
libpurple/prefs.c
-libpurple/presence.c
libpurple/protocol.c
libpurple/protocols/bonjour/bonjour.c
libpurple/protocols/bonjour/bonjour_ft.c
@@ -270,6 +269,7 @@
libpurple/purplecredentialprovider.c
libpurple/purpleimconversation.c
libpurple/purplemarkup.c
+libpurple/purplepresence.c
libpurple/purpleprotocolim.c
libpurple/purpleprotocolmedia.c
libpurple/purpleprotocolprivacy.c