--- a/libpurple/purplepresence.c Tue Mar 21 02:07:16 2023 -0500
+++ b/libpurple/purplepresence.c Tue Mar 21 02:36:13 2023 -0500
@@ -36,6 +36,11 @@
GHashTable *status_table;
PurpleStatus *active_status;
+ PurplePresencePrimitive primitive; @@ -46,6 +51,8 @@
static GParamSpec *properties[N_PROPERTIES];
@@ -98,6 +105,18 @@
purple_presence_set_active_status(presence,
g_value_get_object(value));
+ purple_presence_set_primitive(presence, g_value_get_enum(value)); + purple_presence_set_message(presence, g_value_get_string(value)); + purple_presence_set_emoji(presence, g_value_get_string(value)); + purple_presence_set_mobile(presence, g_value_get_boolean(value)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -129,6 +148,12 @@
g_value_set_string(value, purple_presence_get_message(presence));
+ g_value_set_string(value, purple_presence_get_emoji(presence)); + g_value_set_boolean(value, purple_presence_get_mobile(presence)); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
@@ -157,6 +182,9 @@
g_clear_pointer(&priv->idle_time, g_date_time_unref);
g_clear_pointer(&priv->login_time, g_date_time_unref);
+ g_clear_pointer(&priv->message, g_free); + g_clear_pointer(&priv->emoji, g_free); G_OBJECT_CLASS(purple_presence_parent_class)->finalize(obj);
@@ -219,9 +247,9 @@
properties[PROP_PRIMITIVE] = g_param_spec_enum(
"primitive", "primitive",
"The primitive for the presence",
- PURPLE_TYPE_STATUS_PRIMITIVE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ PURPLE_TYPE_PRESENCE_PRIMITIVE, + PURPLE_PRESENCE_PRIMITIVE_OFFLINE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); * PurplePresence:message:
@@ -234,7 +262,33 @@
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurplePresence:emoji: + * The emoji or mood of the presence. + properties[PROP_EMOJI] = g_param_spec_string( + "The emoji for the presence.", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + * PurplePresence:mobile: + * Whether or not the presence is on a mobile device. + properties[PROP_MOBILE] = g_param_spec_boolean( + "Whether or not the presence is on a mobile device.", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
@@ -557,21 +611,34 @@
purple_presence_get_primitive(PurplePresence *presence) {
PurplePresencePrivate *priv = NULL;
- PurpleStatusType *type = NULL;
- g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), PURPLE_STATUS_UNSET);
+ g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), + PURPLE_PRESENCE_PRIMITIVE_OFFLINE); priv = purple_presence_get_instance_private(presence);
- type = purple_status_get_status_type(priv->active_status);
- return purple_status_type_get_primitive(type);
+ return priv->primitive; +purple_presence_set_primitive(PurplePresence *presence, + PurplePresencePrimitive primitive) + PurplePresencePrivate *priv = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + priv = purple_presence_get_instance_private(presence); + if(priv->primitive != primitive) { + priv->primitive = primitive; + g_object_notify_by_pspec(G_OBJECT(presence), + properties[PROP_PRIMITIVE]);
- return PURPLE_STATUS_UNSET;
@@ -582,9 +649,82 @@
priv = purple_presence_get_instance_private(presence);
+ if(priv->message != NULL) { return purple_status_get_attr_string(priv->active_status, "message");
+purple_presence_set_message(PurplePresence *presence, const char *message) { + PurplePresencePrivate *priv = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + priv = purple_presence_get_instance_private(presence); + if(!purple_strequal(priv->message, message)) { + priv->message = g_strdup(message); + g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_MESSAGE]); +purple_presence_get_emoji(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL); + priv = purple_presence_get_instance_private(presence); +purple_presence_set_emoji(PurplePresence *presence, const char *emoji) { + PurplePresencePrivate *priv = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + priv = purple_presence_get_instance_private(presence); + if(!purple_strequal(priv->emoji, emoji)) { + priv->emoji = g_strdup(emoji); + g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_EMOJI]); +purple_presence_get_mobile(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + priv = purple_presence_get_instance_private(presence); +purple_presence_set_mobile(PurplePresence *presence, gboolean mobile) { + PurplePresencePrivate *priv = NULL; + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + priv = purple_presence_get_instance_private(presence); + if(priv->mobile != mobile) { + g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_MOBILE]); purple_presence_primitive_to_string(PurplePresencePrimitive primitive) {
--- a/libpurple/purplepresence.h Tue Mar 21 02:07:16 2023 -0500
+++ b/libpurple/purplepresence.h Tue Mar 21 02:36:13 2023 -0500
@@ -298,13 +298,24 @@
* purple_presence_get_primitive:
* @presence: The instance.
- * Gets the [enum@Purple.StatusPrimitive] for @presence.
+ * Gets the [enum@Purple.PresencePrimitive] for @presence. * Returns: The current primitive.
-PurpleStatusPrimitive purple_presence_get_primitive(PurplePresence *presence);
+PurplePresencePrimitive purple_presence_get_primitive(PurplePresence *presence); + * purple_presence_set_primitive: + * @presence: The instance. + * @primitive: The new primitive. + * Sets the [enum@Purple.StatusPrimitive] for @presence to @primitive. +void purple_presence_set_primitive(PurplePresence *presence, PurplePresencePrimitive primitive); * purple_presence_get_message:
@@ -319,6 +330,64 @@
const char *purple_presence_get_message(PurplePresence *presence);
+ * purple_presence_set_message: + * @presence: The instance. + * @message: (nullable): The new message. + * Sets the status message of @presence to @message. +void purple_presence_set_message(PurplePresence *presence, const char *message); + * purple_presence_get_emoji: + * @presence: The instance. + * Gets the current emoji, sometimes referred to as a mood, of @presence. + * Returns: The current emoji or %NULL if none is set. +const char *purple_presence_get_emoji(PurplePresence *presence); + * purple_presence_set_emoji: + * @presence: The instance. + * @emoji: (nullable): The new emoji to set. + * Sets the current emoji, sometimes referred to as a mood, of @presence to +void purple_presence_set_emoji(PurplePresence *presence, const char *emoji); + * purple_presence_get_mobile: + * @presence: The instance. + * Gets whether or not @presence is on a mobile device. + * Returns: %TRUE if @presence is on a mobile device, otherwise %FALSE. +gboolean purple_presence_get_mobile(PurplePresence *presence); + * purple_presence_set_mobile: + * @presence: The instance. + * @mobile: The new mobile status. + * Sets whether or not @presence is on a mobile device. +void purple_presence_set_mobile(PurplePresence *presence, gboolean mobile); * purple_presence_primitive_to_string:
* @primitive: The [enum@Purple.PresencePrimitive] value.
--- a/libpurple/tests/test_presence.c Tue Mar 21 02:07:16 2023 -0500
+++ b/libpurple/tests/test_presence.c Tue Mar 21 02:36:13 2023 -0500
@@ -24,65 +24,79 @@
*****************************************************************************/
-test_purple_presence_migrate_online_without_message(void) {
+test_purple_presence_new(void) { PurplePresence *presence = NULL;
- PurpleStatus *status = NULL;
- PurpleStatusType *type = NULL;
- type = purple_status_type_new(PURPLE_STATUS_AVAILABLE,
- "online", "online", TRUE);
presence = purple_presence_new();
- status = purple_status_new(type, presence);
- purple_status_set_active(status, TRUE);
- /* Now verify that the presence returns the correct values for the
- g_assert_cmpint(purple_presence_get_primitive(presence), ==,
- PURPLE_STATUS_AVAILABLE);
- g_assert_null(purple_presence_get_message(presence));
+ g_assert_true(PURPLE_IS_PRESENCE(presence)); g_clear_object(&presence);
- g_clear_object(&status);
- g_clear_pointer(&type, purple_status_type_destroy);
-test_purple_presence_migrate_online_with_message(void) {
+test_purple_presence_properties(void) { PurplePresence *presence = NULL;
- PurpleStatus *status = NULL;
- PurpleStatusType *type = NULL;
- GHashTable *attrs = NULL;
+ PurplePresencePrimitive primitive = PURPLE_PRESENCE_PRIMITIVE_OFFLINE; + GDateTime *login = NULL; + GDateTime *login1 = NULL; + GDateTime *idle = NULL; + GDateTime *idle1 = NULL; + gboolean mobile = FALSE; - type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
- purple_value_new(G_TYPE_STRING),
- presence = purple_presence_new();
+ /* Create the login and idle times. */ + now = g_date_time_new_now_utc(); + login = g_date_time_add_hours(now, -1); + idle = g_date_time_add_minutes(now, -10); + g_clear_pointer(&now, g_date_time_unref); - status = purple_status_new(type, presence);
- attrs = g_hash_table_new(g_str_hash, g_str_equal);
- g_hash_table_insert(attrs, "message", "Greetings Programs!");
- purple_status_set_active_with_attributes(status, TRUE, attrs);
- g_hash_table_destroy(attrs);
+ /* Create the presence using g_object_new to make sure set_property is + presence = g_object_new( + "primitive", PURPLE_PRESENCE_PRIMITIVE_AVAILABLE, + "message", "I'll be back!", - /* Now verify that the presence returns the correct values for the
+ /* Grab the values via g_object_get to make sure get_property is wired up - g_assert_cmpint(purple_presence_get_primitive(presence), ==,
- PURPLE_STATUS_AVAILABLE);
- g_assert_cmpstr(purple_presence_get_message(presence), ==,
- "Greetings Programs!");
+ "primitive", &primitive, + g_assert_cmpint(primitive, ==, PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); + g_assert_cmpstr(message, ==, "I'll be back!"); + g_assert_cmpstr(emoji, ==, "🤖"); + g_assert_nonnull(login1); + g_assert_true(g_date_time_equal(login, login1)); + g_assert_nonnull(idle1); + g_assert_true(g_date_time_equal(idle, idle1)); + g_clear_pointer(&message, g_free); + g_clear_pointer(&emoji, g_free); + g_clear_pointer(&login, g_date_time_unref); + g_clear_pointer(&login1, g_date_time_unref); + g_clear_pointer(&idle, g_date_time_unref); + g_clear_pointer(&idle1, g_date_time_unref); g_clear_object(&presence);
- g_clear_object(&status);
- g_clear_pointer(&type, purple_status_type_destroy);
/******************************************************************************
@@ -92,14 +106,8 @@
main(gint argc, gchar *argv[]) {
g_test_init(&argc, &argv, NULL);
- /* This tests verify that PurplePresence is properly notifying of property
- * changes with the 2.x.y and earlier status back end. When PurplePresence
- * has replaced that back end, these tests should be removed as well.
- g_test_add_func("/presence/migrate/online-without-message",
- test_purple_presence_migrate_online_without_message);
- g_test_add_func("/presence/migrate/online-with-message",
- test_purple_presence_migrate_online_with_message);
+ g_test_add_func("/presence/new", test_purple_presence_new); + g_test_add_func("/presence/properties", test_purple_presence_properties);