Sun, 01 Nov 2020 03:33:09 -0600
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