Rename presence.[ch] to purplepresence.[ch], fix some docs, and other tweaks.

Sun, 01 Nov 2020 03:33:09 -0600

author
Gary Kramlich <grim@reaperworld.com>
date
Sun, 01 Nov 2020 03:33:09 -0600
changeset 40575
b82c365e04e8
parent 40574
98384d15c7a0
child 40576
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/

doc/reference/libpurple/libpurple-docs.xml file | annotate | diff | comparison | revisions
libpurple/buddy.h file | annotate | diff | comparison | revisions
libpurple/group.h file | annotate | diff | comparison | revisions
libpurple/meson.build file | annotate | diff | comparison | revisions
libpurple/presence.c file | annotate | diff | comparison | revisions
libpurple/presence.h file | annotate | diff | comparison | revisions
libpurple/purpleaccountpresence.h file | annotate | diff | comparison | revisions
libpurple/purplebuddypresence.h file | annotate | diff | comparison | revisions
libpurple/purplepresence.c file | annotate | diff | comparison | revisions
libpurple/purplepresence.h file | annotate | diff | comparison | revisions
libpurple/status.h file | annotate | diff | comparison | revisions
po/POTFILES.in file | annotate | diff | comparison | revisions
--- 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

mercurial