Fri, 12 Apr 2024 02:08:00 -0500
Remove the old status API
This has been a long time coming, but it's finally here!!
Testing Done:
April O'Neil covered it on the news!
I also ran the program and verified the demo protocol plugin was still working.
Reviewed at https://reviews.imfreedom.org/r/3103/
--- a/ChangeLog.API Fri Apr 12 01:55:22 2024 -0500 +++ b/ChangeLog.API Fri Apr 12 02:08:00 2024 -0500 @@ -248,6 +248,7 @@ instead. * account-setting-info, account-set-info signals * account-status-changing signal. + * buddy-status-changed signal. * chat-topic-changed signal. * file-recv-accept, file-recv-cancel, file-recv-complete, file-recv-start, file-send-accept, file-send-cancel, @@ -273,6 +274,7 @@ * purple_account_add_buddies_with_invite * purple_account_add_buddy_with_invite * purple_account_destroy_log + * purple_account_get_active_status * purple_account_get_check_mail * purple_account_get_log * purple_account_get_name_for_display. Use @@ -284,11 +286,16 @@ * purple_account_get_private_alias. Use purple_contact_get_alias instead. * purple_account_get_silence_suppression + * purple_account_get_status + * purple_account_get_status_type + * purple_account_get_status_type_with_primitive + * purple_account_get_status_types * purple_account_get_ui_int * purple_account_get_ui_string * purple_account_get_ui_bool * purple_account_get_username. Use purple_contact_info_get_username instead. + * purple_account_is_status_active * purple_account_notify_added * purple_account_privacy_allow * purple_account_privacy_check @@ -313,11 +320,15 @@ instead. * purple_account_set_public_alias * purple_account_set_silence_suppression + * purple_account_set_status + * purple_account_set_status_attrs + * purple_account_set_status_types * purple_account_set_ui_int * purple_account_set_ui_string * purple_account_set_ui_bool * purple_account_set_username. Use purple_contact_info_set_username instead. + * account-status-changed signal * purple_accounts_add * purple_accounts_find * purple_accounts_get_all @@ -605,6 +616,12 @@ * PurplePounceEvent * PurplePounceOption * PurplePrefsUiOps + * purple_presence_get_status + * purple_presence_get_statuses + * purple_presence_is_status_active + * purple_presence_is_status_primitive_active + * purple_presence_set_status_active + * purple_presence_switch_status * purple_protocol_got_account_actions * purple_protocol_got_account_idle * purple_protocol_got_account_status
--- a/doc/reference/libpurple/libpurple.toml.in Fri Apr 12 01:55:22 2024 -0500 +++ b/doc/reference/libpurple/libpurple.toml.in Fri Apr 12 02:08:00 2024 -0500 @@ -47,7 +47,6 @@ "signals_conversation.md", "signals_core.md", "signals_jabber.md", - "signals_savedstatus.md", "tut_c_plugins.md", ] content_images = [
--- a/doc/reference/libpurple/meson.build Fri Apr 12 01:55:22 2024 -0500 +++ b/doc/reference/libpurple/meson.build Fri Apr 12 02:08:00 2024 -0500 @@ -8,8 +8,6 @@ 'signals_connection.md', 'signals_conversation.md', 'signals_core.md', - 'signals_jabber.md', - 'signals_savedstatus.md', 'tut_c_plugins.md', ]
--- a/doc/reference/libpurple/signals_account.md Fri Apr 12 01:55:22 2024 -0500 +++ b/doc/reference/libpurple/signals_account.md Fri Apr 12 02:08:00 2024 -0500 @@ -5,7 +5,6 @@ ### Signal List -* [account-status-changed](#account-status-changed) * [account-signed-on](#account-signed-on) * [account-signed-off](#account-signed-off) @@ -47,33 +46,6 @@ ---- -#### account-status-changed - -```c -void user_function(PurpleAccount *account, - PurpleStatus *old, - PurpleStatus *new, - gpointer user_data); -``` - -Emitted when the status of an account changes (after the change). - -**Parameters:** - -**account** -: The account that changed status. - -**old** -: The status before change. - -**new** -: The status after change. - -**user_data** -: User data set when the signal handler was connected. - ----- - #### account-signed-on ```c
--- a/doc/reference/libpurple/signals_blist.md Fri Apr 12 01:55:22 2024 -0500 +++ b/doc/reference/libpurple/signals_blist.md Fri Apr 12 02:08:00 2024 -0500 @@ -5,7 +5,6 @@ ### Signal List -* [buddy-status-changed](#buddy-status-changed) * [buddy-idle-changed](#buddy-idle-changed) * [buddy-signed-on](#buddy-signed-on) * [buddy-signed-off](#buddy-signed-off) @@ -18,33 +17,6 @@ ### Signal Details -#### buddy-status-changed - -```c -void user_function(PurpleBuddy *buddy, - PurpleStatus *old_status, - PurpleStatus *status, - gpointer user_data); -``` - -Emitted when a buddy on your buddy list goes away. - -**Parameters:** - -**buddy** -: The buddy whose status changed. - -**old_status** -: The status that the buddy just changed from. - -**status** -: The status that the buddy just changed to. - -**user_data** -: user data set when the signal handler was connected. - ----- - #### buddy-idle-changed ```c
--- a/doc/reference/libpurple/signals_savedstatus.md Fri Apr 12 01:55:22 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -Title: Saved Status Signals -Slug: saved-status-signals - -## Saved Status Signals - -### Signal List - -* [savedstatus-changed](#savedstatus-changed) - -### Signal Details - -#### savedstatus-changed - -```c -void user_function(PurpleSavedStatus *new, - PurpleSavedStatus *old, - gpointer user_data); -``` - -Emitted when a new saved status is activated.
--- a/libpurple/accounts.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/accounts.c Fri Apr 12 02:08:00 2024 -0500 @@ -625,11 +625,6 @@ void *handle = purple_accounts_get_handle(); void *conn_handle = purple_connections_get_handle(); - purple_signal_register(handle, "account-status-changed", - purple_marshal_VOID__POINTER_POINTER_POINTER, - G_TYPE_NONE, 3, PURPLE_TYPE_ACCOUNT, - PURPLE_TYPE_STATUS, PURPLE_TYPE_STATUS); - purple_signal_register(handle, "account-signed-on", purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, PURPLE_TYPE_ACCOUNT);
--- a/libpurple/buddy.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/buddy.c Fri Apr 12 02:08:00 2024 -0500 @@ -191,7 +191,8 @@ } priv->presence = purple_presence_new(); - purple_presence_set_status_active(priv->presence, "offline", TRUE); + purple_presence_set_primitive(priv->presence, + PURPLE_PRESENCE_PRIMITIVE_OFFLINE); purple_blist_new_node(purple_blist_get_default(), PURPLE_BLIST_NODE(buddy)); @@ -704,78 +705,6 @@ return priv->presence; } -void -purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status) { - PurpleBuddyList *blist = NULL; - PurpleBuddyPrivate *priv = NULL; - PurpleStatus *status = NULL; - gpointer handle = NULL; - - gboolean old_online = FALSE, new_online = FALSE; - - g_return_if_fail(PURPLE_IS_BUDDY(buddy)); - - priv = purple_buddy_get_instance_private(buddy); - status = purple_presence_get_active_status(priv->presence); - blist = purple_blist_get_default(); - handle = purple_blist_get_handle(); - - purple_debug_info("blistnodetypes", "Updating buddy status for %s (%s)\n", - priv->name, - purple_account_get_protocol_name(priv->account)); - - old_online = purple_status_is_online(old_status); - new_online = purple_status_is_online(status); - - if(old_online != new_online) { - PurpleBlistNode *cnode = NULL, *gnode = NULL; - PurpleMetaContact *contact = NULL; - PurpleCountingNode *contact_counter = NULL, *group_counter = NULL; - gint delta = 0, limit = 0; - - if(new_online) { - purple_signal_emit(handle, "buddy-signed-on", buddy); - delta = 1; - limit = 1; - } else { - purple_blist_node_set_int(PURPLE_BLIST_NODE(buddy), "last_seen", - time(NULL)); - - purple_signal_emit(handle, "buddy-signed-off", buddy); - delta = -1; - limit = 0; - } - - cnode = purple_blist_node_get_parent(PURPLE_BLIST_NODE(buddy)); - contact = PURPLE_META_CONTACT(cnode); - contact_counter = PURPLE_COUNTING_NODE(contact); - gnode = purple_blist_node_get_parent(cnode); - group_counter = PURPLE_COUNTING_NODE(gnode); - - purple_counting_node_change_online_count(contact_counter, delta); - if(purple_counting_node_get_online_count(contact_counter) == limit) { - purple_counting_node_change_online_count(group_counter, delta); - } - } else { - purple_signal_emit(handle, "buddy-status-changed", buddy, old_status, - status); - } - - /* - * This function used to only call the following two functions if one of - * the above signals had been triggered, but that's not good, because - * if someone's away message changes and they don't go from away to back - * to away then no signal is triggered. - * - * It's a safe assumption that SOMETHING called this function. PROBABLY - * because something, somewhere changed. Calling the stuff below - * certainly won't hurt anything. Unless you're on a K6-2 300. - */ - purple_meta_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy)); - - purple_blist_update_node(blist, PURPLE_BLIST_NODE(buddy)); -} - PurpleMediaCaps purple_buddy_get_media_caps(PurpleBuddy *buddy) { PurpleBuddyPrivate *priv = NULL;
--- a/libpurple/buddy.h Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/buddy.h Fri Apr 12 02:08:00 2024 -0500 @@ -46,7 +46,6 @@ #include "purpleaccount.h" #include "purplepresence.h" #include "purpleversion.h" -#include "status.h" /** * PURPLE_BUDDY_IS_ONLINE: @@ -271,20 +270,6 @@ PurplePresence *purple_buddy_get_presence(PurpleBuddy *buddy); /** - * purple_buddy_update_status: - * @buddy: The buddy whose status has changed. - * @old_status: The status from which we are changing. - * - * Updates a buddy's status. - * - * This should only be called from within Purple. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_buddy_update_status(PurpleBuddy *buddy, PurpleStatus *old_status); - -/** * purple_buddy_get_media_caps: * @buddy: The buddy. *
--- a/libpurple/buddylist.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/buddylist.c Fri Apr 12 02:08:00 2024 -0500 @@ -1912,7 +1912,8 @@ for (iter = list; iter; iter = iter->next) { - purple_presence_set_status_active(iter->data, "offline", TRUE); + purple_presence_set_primitive(iter->data, + PURPLE_PRESENCE_PRIMITIVE_OFFLINE); } g_list_free(list); } @@ -2084,10 +2085,6 @@ /* Set a default, which can't be done as a static initializer. */ buddy_list_type = PURPLE_TYPE_BUDDY_LIST; - purple_signal_register(handle, "buddy-status-changed", - purple_marshal_VOID__POINTER_POINTER_POINTER, - G_TYPE_NONE, 3, PURPLE_TYPE_BUDDY, PURPLE_TYPE_STATUS, - PURPLE_TYPE_STATUS); purple_signal_register(handle, "buddy-privacy-changed", purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, PURPLE_TYPE_BUDDY);
--- a/libpurple/connection.h Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/connection.h Fri Apr 12 02:08:00 2024 -0500 @@ -112,7 +112,6 @@ #include "purpleaccount.h" #include "purpleconnectionerrorinfo.h" #include "purpleprotocol.h" -#include "status.h" struct _PurpleConnectionClass { /*< private >*/
--- a/libpurple/core.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/core.c Fri Apr 12 02:08:00 2024 -0500 @@ -44,9 +44,7 @@ #include "purplepath.h" #include "purplepresencemanagerprivate.h" #include "purpleprivate.h" -#include "savedstatuses.h" #include "signals.h" -#include "status.h" #include "util.h" #ifdef _WIN32 #include "win32/win32dep.h" @@ -149,17 +147,15 @@ */ purple_plugins_init(); - /* Accounts use status, buddy icons and connection signals, so - * initialize these before accounts + /* Accounts buddy icons and connection signals, so initialize these before + * accounts. */ - purple_statuses_init(); purple_buddy_icons_init(); purple_connections_init(); purple_account_manager_startup(); purple_accounts_init(); purple_contact_manager_startup(); - purple_savedstatuses_init(); purple_presence_manager_startup(); purple_notify_init(); purple_conversations_init(); @@ -241,8 +237,6 @@ purple_connections_uninit(); purple_buddy_icons_uninit(); purple_presence_manager_shutdown(); - purple_savedstatuses_uninit(); - purple_statuses_uninit(); purple_accounts_uninit(); purple_proxy_uninit(); purple_network_uninit();
--- a/libpurple/meson.build Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/meson.build Fri Apr 12 02:08:00 2024 -0500 @@ -112,10 +112,8 @@ 'request/purplerequestpage.c', 'request-datasheet.c', 'roomlist.c', - 'savedstatuses.c', 'server.c', 'signals.c', - 'status.c', 'util.c', 'xmlnode.c' ] @@ -221,10 +219,8 @@ 'request.h', 'request-datasheet.h', 'roomlist.h', - 'savedstatuses.h', 'server.h', 'signals.h', - 'status.h', 'util.h', 'xmlnode.h', ] @@ -312,7 +308,6 @@ 'purpleproxyinfo.h', 'purpletyping.h', 'roomlist.h', - 'status.h', 'xmlnode.h' ]
--- a/libpurple/purpleaccount.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purpleaccount.c Fri Apr 12 02:08:00 2024 -0500 @@ -74,8 +74,6 @@ PurpleProxyInfo *proxy_info; - GList *status_types; - PurplePresence *presence; PurpleConnectionErrorInfo *error; @@ -807,8 +805,6 @@ purple_account_free_notify_settings(account); - purple_account_set_status_types(account, NULL); - g_clear_object(&account->proxy_info); g_clear_pointer(&account->error, purple_connection_error_info_free); @@ -1419,65 +1415,6 @@ } void -purple_account_set_status_types(PurpleAccount *account, GList *status_types) { - g_return_if_fail(PURPLE_IS_ACCOUNT(account)); - - /* Out with the old... */ - g_list_free_full(account->status_types, - (GDestroyNotify)purple_status_type_destroy); - - /* In with the new... */ - account->status_types = status_types; -} - -void -purple_account_set_status(PurpleAccount *account, const char *status_id, - gboolean active, ...) -{ - GHashTable *attrs; - va_list args; - - va_start(args, active); - attrs = purple_attrs_from_vargs(args); - purple_account_set_status_attrs(account, status_id, active, attrs); - g_hash_table_destroy(attrs); - va_end(args); -} - -void -purple_account_set_status_attrs(PurpleAccount *account, const char *status_id, - gboolean active, GHashTable *attrs) -{ - PurpleStatus *status; - - g_return_if_fail(PURPLE_IS_ACCOUNT(account)); - g_return_if_fail(status_id != NULL); - - status = purple_account_get_status(account, status_id); - if(status == NULL) { - PurpleContactInfo *info = PURPLE_CONTACT_INFO(account); - - purple_debug_error("account", - "Invalid status ID '%s' for account %s (%s)\n", - status_id, - purple_contact_info_get_username(info), - purple_account_get_protocol_id(account)); - - return; - } - - if(active || purple_status_is_independent(status)) { - purple_status_set_active_with_attributes(status, active, attrs); - } - - /* - * Our current statuses are saved to accounts.xml (so that when we - * reconnect, we go back to the previous status). - */ - purple_accounts_schedule_save(); -} - -void purple_account_set_int(PurpleAccount *account, const char *name, int value) { PurpleAccountSetting *setting; @@ -1631,59 +1568,6 @@ return account->proxy_info; } -PurpleStatus * -purple_account_get_active_status(PurpleAccount *account) { - g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); - - return purple_presence_get_active_status(account->presence); -} - -PurpleStatus * -purple_account_get_status(PurpleAccount *account, const char *status_id) { - g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); - g_return_val_if_fail(status_id != NULL, NULL); - - return purple_presence_get_status(account->presence, status_id); -} - -PurpleStatusType * -purple_account_get_status_type(PurpleAccount *account, const char *id) { - GList *l; - - g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); - g_return_val_if_fail(id != NULL, NULL); - - for (l = purple_account_get_status_types(account); l != NULL; l = l->next) - { - PurpleStatusType *status_type = (PurpleStatusType *)l->data; - - if(purple_strequal(purple_status_type_get_id(status_type), id)) { - return status_type; - } - } - - return NULL; -} - -PurpleStatusType * -purple_account_get_status_type_with_primitive(PurpleAccount *account, - PurpleStatusPrimitive primitive) -{ - GList *l; - - g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); - - for(l = purple_account_get_status_types(account); l != NULL; l = l->next) { - PurpleStatusType *status_type = (PurpleStatusType *)l->data; - - if(purple_status_type_get_primitive(status_type) == primitive) { - return status_type; - } - } - - return NULL; -} - PurplePresence * purple_account_get_presence(PurpleAccount *account) { g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); @@ -1691,23 +1575,6 @@ return account->presence; } -gboolean -purple_account_is_status_active(PurpleAccount *account, - const char *status_id) -{ - g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), FALSE); - g_return_val_if_fail(status_id != NULL, FALSE); - - return purple_presence_is_status_active(account->presence, status_id); -} - -GList * -purple_account_get_status_types(PurpleAccount *account) { - g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL); - - return account->status_types; -} - int purple_account_get_int(PurpleAccount *account, const char *name, int default_value)
--- a/libpurple/purpleaccount.h Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purpleaccount.h Fri Apr 12 02:08:00 2024 -0500 @@ -41,7 +41,6 @@ #include "purpleprotocol.h" #include "purpleproxyinfo.h" #include "purpleversion.h" -#include "status.h" G_BEGIN_DECLS @@ -253,71 +252,6 @@ void purple_account_set_proxy_info(PurpleAccount *account, PurpleProxyInfo *info); /** - * purple_account_set_status_types: - * @account: The account. - * @status_types: (element-type PurpleStatusType): The list of status types. - * - * Sets the account's status types. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_account_set_status_types(PurpleAccount *account, GList *status_types); - -/** - * purple_account_set_status: - * @account: The account. - * @status_id: The ID of the status. - * @active: Whether @status_id is to be activated (%TRUE) or deactivated - * (%FALSE). - * @...: A %NULL-terminated list of pairs of `const char *` attribute name - * followed by `const char *` attribute value for the status. (For - * example, one pair might be `"message"` followed by `"hello, talk to - * me!"`.) - * - * Activates or deactivates a status. - * - * All changes to the statuses of an account go through this function or - * [method@Purple.Account.set_status_attrs]. - * - * You can only deactivate an exclusive status by activating another exclusive - * status. So, if @status_id is an exclusive status and @active is %FALSE, this - * function does nothing. - * - * Variadic version of [method@Purple.Account.set_status_attrs]. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_account_set_status(PurpleAccount *account, const char *status_id, gboolean active, ...) G_GNUC_NULL_TERMINATED; - - -/** - * purple_account_set_status_attrs: (rename-to purple_account_set_status): - * @account: The account. - * @status_id: The ID of the status. - * @active: Whether @status_id is to be activated (%TRUE) or deactivated - * (%FALSE). - * @attrs: (element-type utf8 utf8): A hash table with keys of attribute - * names and values of attributes for the status. (For example, one - * pair might be a key of `"message"` with a value of `"hello, talk to - * me!"`.) - * - * Activates or deactivates a status. - * - * All changes to the statuses of an account go through this function or - * [method@Purple.Account.set_status]. - * - * You can only deactivate an exclusive status by activating another exclusive - * status. So, if @status_id is an exclusive status and @active is %FALSE, this - * function does nothing. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_account_set_status_attrs(PurpleAccount *account, const char *status_id, gboolean active, GHashTable *attrs); - -/** * purple_account_set_int: * @account: The account. * @name: The name of the setting. @@ -514,67 +448,6 @@ PurpleProxyInfo *purple_account_get_proxy_info(PurpleAccount *account); /** - * purple_account_get_active_status: - * @account: The account. - * - * Returns the active status for this account. This looks through - * the PurplePresence associated with this account and returns the - * PurpleStatus that has its active flag set to "TRUE." There can be - * only one active PurpleStatus in a PurplePresence. - * - * Returns: (transfer none): The active status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatus *purple_account_get_active_status(PurpleAccount *account); - -/** - * purple_account_get_status: - * @account: The account. - * @status_id: The status ID. - * - * Returns the account status with the specified ID. - * - * Returns: (transfer none): The status, or %NULL if it was never registered. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatus *purple_account_get_status(PurpleAccount *account, const char *status_id); - -/** - * purple_account_get_status_type: - * @account: The account. - * @id: The ID of the status type to find. - * - * Returns the account status type with the specified ID. - * - * Returns: The status type if found, or %NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusType *purple_account_get_status_type(PurpleAccount *account, const char *id); - -/** - * purple_account_get_status_type_with_primitive: - * @account: The account. - * @primitive: The type of the status type to find. - * - * Returns the account status type with the specified primitive. - * Note: It is possible for an account to have more than one - * PurpleStatusType with the same primitive. In this case, the - * first PurpleStatusType is returned. - * - * Returns: The status if found, or %NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusType *purple_account_get_status_type_with_primitive(PurpleAccount *account, PurpleStatusPrimitive primitive); - -/** * purple_account_get_presence: * @account: The account. * @@ -588,33 +461,6 @@ PurplePresence *purple_account_get_presence(PurpleAccount *account); /** - * purple_account_is_status_active: - * @account: The account. - * @status_id: The status ID. - * - * Returns whether or not an account status is active. - * - * Returns: TRUE if active, or FALSE if not. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_account_is_status_active(PurpleAccount *account, const char *status_id); - -/** - * purple_account_get_status_types: - * @account: The account. - * - * Returns the account's status types. - * - * Returns: (transfer none) (element-type PurpleStatusType): The account's status types. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GList *purple_account_get_status_types(PurpleAccount *account); - -/** * purple_account_get_int: * @account: The account. * @name: The name of the setting.
--- a/libpurple/purplepresence.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purplepresence.c Fri Apr 12 02:08:00 2024 -0500 @@ -33,10 +33,6 @@ GDateTime *idle_time; GDateTime *login_time; - GHashTable *status_table; - - PurpleStatus *active_status; - PurplePresencePrimitive primitive; char *message; char *emoji; @@ -49,7 +45,6 @@ PROP_IDLE, PROP_IDLE_TIME, PROP_LOGIN_TIME, - PROP_ACTIVE_STATUS, PROP_PRIMITIVE, PROP_MESSAGE, PROP_EMOJI, @@ -62,28 +57,6 @@ 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)) { - GObject *obj = G_OBJECT(presence); - - g_object_freeze_notify(obj); - g_object_notify_by_pspec(obj, properties[PROP_ACTIVE_STATUS]); - g_object_notify_by_pspec(obj, properties[PROP_PRIMITIVE]); - g_object_notify_by_pspec(obj, properties[PROP_MESSAGE]); - g_object_thaw_notify(obj); - } -} - -/****************************************************************************** * GObject Implementation *****************************************************************************/ static void @@ -103,10 +76,6 @@ case PROP_LOGIN_TIME: purple_presence_set_login_time(presence, g_value_get_boxed(value)); break; - case PROP_ACTIVE_STATUS: - purple_presence_set_active_status(presence, - g_value_get_object(value)); - break; case PROP_PRIMITIVE: purple_presence_set_primitive(presence, g_value_get_enum(value)); break; @@ -145,9 +114,6 @@ case PROP_LOGIN_TIME: g_value_set_boxed(value, purple_presence_get_login_time(presence)); break; - case PROP_ACTIVE_STATUS: - g_value_set_object(value, purple_presence_get_active_status(presence)); - break; case PROP_PRIMITIVE: g_value_set_enum(value, purple_presence_get_primitive(presence)); break; @@ -171,13 +137,7 @@ } 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); +purple_presence_init(G_GNUC_UNUSED PurplePresence *presence) { } static void @@ -186,9 +146,6 @@ priv = purple_presence_get_instance_private(PURPLE_PRESENCE(obj)); - g_hash_table_destroy(priv->status_table); - g_clear_object(&priv->active_status); - g_clear_pointer(&priv->idle_time, g_date_time_unref); g_clear_pointer(&priv->login_time, g_date_time_unref); @@ -244,21 +201,9 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * PurplePresence:active-status: - * - * The currently active status of the presence. - * - * Since: 3.0 - */ - 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); - - /** * PurplePresence:primitive: * - * The [enum@Purple.StatusPrimitive] for this presence. + * The [enum@Purple.PresencePrimitive] for this presence. * * Since: 3.0 */ @@ -337,41 +282,6 @@ } 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, GDateTime *idle_time) { @@ -436,126 +346,37 @@ 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); - } +gboolean +purple_presence_is_available(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; - 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); + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); 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)); + return priv->primitive == PURPLE_PRESENCE_PRIMITIVE_AVAILABLE; } gboolean purple_presence_is_online(PurplePresence *presence) { - PurpleStatus *status = NULL; + PurplePresencePrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); - if((status = purple_presence_get_active_status(presence)) == NULL) { + priv = purple_presence_get_instance_private(presence); + + switch(priv->primitive) { + case PURPLE_PRESENCE_PRIMITIVE_AVAILABLE: + case PURPLE_PRESENCE_PRIMITIVE_IDLE: + case PURPLE_PRESENCE_PRIMITIVE_INVISIBLE: + case PURPLE_PRESENCE_PRIMITIVE_AWAY: + case PURPLE_PRESENCE_PRIMITIVE_DO_NOT_DISTURB: + case PURPLE_PRESENCE_PRIMITIVE_STREAMING: + return TRUE; + case PURPLE_PRESENCE_PRIMITIVE_OFFLINE: + default: 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 @@ -689,15 +510,7 @@ priv = purple_presence_get_instance_private(presence); - if(priv->message != NULL) { - return priv->message; - } - - if(priv->active_status == NULL) { - return NULL; - } - - return purple_status_get_attr_string(priv->active_status, "message"); + return priv->message; } void
--- a/libpurple/purplepresence.h Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purplepresence.h Fri Apr 12 02:08:00 2024 -0500 @@ -52,8 +52,6 @@ typedef struct _PurplePresence PurplePresence; -#include "status.h" - /** * PurplePresencePrimitive: * @PURPLE_PRESENCE_PRIMITIVE_OFFLINE: The presence is offline or otherwise @@ -131,38 +129,6 @@ PurplePresence *purple_presence_new(void); /** - * 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(). - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_presence_set_status_active(PurplePresence *presence, const gchar *status_id, gboolean active); - -/** - * purple_presence_switch_status: - * @presence: The #PurplePresence instance. - * @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. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_presence_switch_status(PurplePresence *presence, const gchar *status_id); - -/** * purple_presence_set_idle: * @presence: The #PurplePresence instance. * @idle: The idle state. @@ -190,46 +156,6 @@ void purple_presence_set_login_time(PurplePresence *presence, GDateTime *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. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -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. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -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. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatus *purple_presence_get_active_status(PurplePresence *presence); - -/** * purple_presence_is_available: * @presence: The #PurplePresence instance. * @@ -258,39 +184,6 @@ 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. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -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. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_presence_is_status_primitive_active(PurplePresence *presence, PurpleStatusPrimitive primitive); - -/** * purple_presence_is_idle: * @presence: The #PurplePresence instance. * @@ -366,7 +259,7 @@ * @presence: The instance. * @primitive: The new primitive. * - * Sets the [enum@Purple.StatusPrimitive] for @presence to @primitive. + * Sets the [enum@Purple.PresencePrimitive] for @presence to @primitive. * * Since: 3.0 */
--- a/libpurple/purpleprotocolserver.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purpleprotocolserver.c Fri Apr 12 02:08:00 2024 -0500 @@ -69,22 +69,6 @@ } void -purple_protocol_server_set_status(PurpleProtocolServer *protocol_server, - PurpleAccount *account, PurpleStatus *status) -{ - PurpleProtocolServerInterface *iface = NULL; - - g_return_if_fail(PURPLE_IS_PROTOCOL_SERVER(protocol_server)); - g_return_if_fail(PURPLE_IS_ACCOUNT(account)); - g_return_if_fail(PURPLE_IS_STATUS(status)); - - iface = PURPLE_PROTOCOL_SERVER_GET_IFACE(protocol_server); - if(iface != NULL && iface->set_status != NULL) { - iface->set_status(protocol_server, account, status); - } -} - -void purple_protocol_server_set_idle(PurpleProtocolServer *protocol_server, PurpleConnection *connection, gint idletime) {
--- a/libpurple/purpleprotocolserver.h Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purpleprotocolserver.h Fri Apr 12 02:08:00 2024 -0500 @@ -63,7 +63,6 @@ void (*set_info)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *info); void (*get_info)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *who); - void (*set_status)(PurpleProtocolServer *protocol_server, PurpleAccount *account, PurpleStatus *status); void (*set_idle)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, gint idletime); void (*change_passwd)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *old_pass, const gchar *new_pass); @@ -116,19 +115,6 @@ void purple_protocol_server_get_info(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *who); /** - * purple_protocol_server_set_status: - * @protocol_server: The #PurpleProtocolServer instance. - * @account: The #PurpleAccount instance. - * @status: The #PurpleStatus instance. - * - * Sets the status for account @account to @status. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_protocol_server_set_status(PurpleProtocolServer *protocol_server, PurpleAccount *account, PurpleStatus *status); - -/** * purple_protocol_server_set_idle: * @protocol_server: The #PurpleProtocolServer instance. * @connection: The #PurpleConnection instance.
--- a/libpurple/purplesavedpresence.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/purplesavedpresence.c Fri Apr 12 02:08:00 2024 -0500 @@ -395,7 +395,7 @@ /** * PurpleSavedPresence:primitive: * - * The [enum@Purple.StatusPrimitive] for this saved presence. + * The [enum@Purple.PresencePrimitive] for this saved presence. * * Since: 3.0 */
--- a/libpurple/savedstatuses.c Fri Apr 12 01:55:22 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1274 +0,0 @@ -/* - * Purple - Internet Messaging Library - * 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 library 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 library 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 library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include <glib/gi18n-lib.h> - -#include "accounts.h" -#include "debug.h" -#include "notify.h" -#include "prefs.h" -#include "purpleaccountmanager.h" -#include "purplemarkup.h" -#include "savedstatuses.h" -#include "request.h" -#include "status.h" -#include "xmlnode.h" - -/* - * The maximum number of transient statuses to save. This - * is used during the shutdown process to clean out old - * transient statuses. - */ -#define MAX_TRANSIENTS 5 - -/* - * The default message to use when the user becomes auto-away. - */ -#define DEFAULT_AUTOAWAY_MESSAGE _("I'm not here right now") - -/* - * The information stores a snap-shot of the statuses of all - * your accounts. Basically these are your saved away messages. - * There is an overall status and message that applies to - * all your accounts, and then each individual account can - * optionally have a different custom status and message. - * - * The changes to status.xml caused by the new status API - * are fully backward compatible. The new status API just - * adds the optional sub-statuses to the XML file. - */ -struct _PurpleSavedStatus -{ - char *title; - PurpleStatusPrimitive type; - char *message; - - /* The timestamp when this saved status was created. This must be unique. */ - time_t creation_time; - - time_t lastused; - - unsigned int usage_count; - - GList *substatuses; /* A list of PurpleSavedStatusSub's. */ -}; - -/* - * TODO: If a PurpleStatusType is deleted, need to also delete any - * associated PurpleSavedStatusSub's? - */ -struct _PurpleSavedStatusSub -{ - PurpleAccount *account; - const PurpleStatusType *type; - char *message; -}; - -static GList *saved_statuses = NULL; -static guint save_timer = 0; -static gboolean statuses_loaded = FALSE; - -/* - * This hash table keeps track of which timestamps we've - * used so that we don't have two saved statuses with the - * same 'creation_time' timestamp. The 'created' timestamp - * is used as a unique identifier. - * - * So the key in this hash table is the creation_time and - * the value is a pointer to the PurpleSavedStatus. - */ -static GHashTable *creation_times; - -static void schedule_save(void); - -/********************************************************************* - * Private utility functions * - *********************************************************************/ - -static void -free_saved_status_sub(PurpleSavedStatusSub *substatus) -{ - g_return_if_fail(substatus != NULL); - - g_free(substatus->message); - purple_request_close_with_handle(substatus); - g_clear_object(&substatus->account); - g_free(substatus); -} - -static void -free_saved_status(PurpleSavedStatus *status) -{ - g_return_if_fail(status != NULL); - - g_free(status->title); - g_free(status->message); - g_list_free_full(status->substatuses, (GDestroyNotify)free_saved_status_sub); - purple_request_close_with_handle(status); - g_free(status); -} - -/* - * Set the timestamp for when this saved status was created, and - * make sure it is unique. - */ -static void -set_creation_time(PurpleSavedStatus *status, time_t creation_time) -{ - g_return_if_fail(status != NULL); - - /* Avoid using 0 because it's an invalid hash key */ - status->creation_time = creation_time != 0 ? creation_time : 1; - - while (g_hash_table_lookup(creation_times, (gconstpointer)status->creation_time) != NULL) - status->creation_time++; - - g_hash_table_insert(creation_times, - (gpointer)status->creation_time, - status); -} - -/* - * A magic number is calculated for each status, and then the - * statuses are ordered by the magic number. The magic number - * is the date the status was last used offset by one day for - * each time the status has been used (but only by 10 days at - * the most). - * - * The goal is to have recently used statuses at the top of - * the list, but to also keep frequently used statuses near - * the top. - */ -static gint -saved_statuses_sort_func(gconstpointer a, gconstpointer b) -{ - const PurpleSavedStatus *saved_status_a = a; - const PurpleSavedStatus *saved_status_b = b; - time_t time_a = saved_status_a->lastused + - (MIN(saved_status_a->usage_count, 10) * 86400); - time_t time_b = saved_status_b->lastused + - (MIN(saved_status_b->usage_count, 10) * 86400); - if (time_a > time_b) - return -1; - if (time_a < time_b) - return 1; - return 0; -} - -/* - * Transient statuses are added and removed automatically by - * Purple. If they're not used for a certain length of time then - * they'll expire and be automatically removed. This function - * does the expiration. - */ -static void -remove_old_transient_statuses(void) -{ - GList *l, *next; - PurpleSavedStatus *saved_status, *startup_status, *current_status; - int count; - time_t creation_time; - - startup_status = purple_savedstatus_get_startup(); - current_status = purple_savedstatus_get_current(); - - /* - * Iterate through the list of saved statuses. Delete all - * transient statuses except for the first MAX_TRANSIENTS - * (remember, the saved statuses are already sorted by popularity). - * We should also keep the startup status, if any is set. - */ - count = 0; - for (l = saved_statuses; l != NULL; l = next) - { - next = l->next; - saved_status = l->data; - if (purple_savedstatus_is_transient(saved_status)) - { - if (count == MAX_TRANSIENTS) - { - if (saved_status != current_status && saved_status != startup_status) - { - saved_statuses = g_list_delete_link(saved_statuses, l); - creation_time = purple_savedstatus_get_creation_time(saved_status); - g_hash_table_remove(creation_times, (gconstpointer)creation_time); - free_saved_status(saved_status); - } - } - else - count++; - } - } - - if (count == MAX_TRANSIENTS) - schedule_save(); -} - -/********************************************************************* - * Writing to disk * - *********************************************************************/ - -static PurpleXmlNode * -substatus_to_xmlnode(PurpleSavedStatusSub *substatus) -{ - PurpleContactInfo *info = NULL; - PurpleXmlNode *node, *child; - const char *name = NULL; - - info = PURPLE_CONTACT_INFO(substatus->account); - - node = purple_xmlnode_new("substatus"); - - child = purple_xmlnode_new_child(node, "account"); - purple_xmlnode_set_attrib(child, "protocol", purple_account_get_protocol_id(substatus->account)); - - name = purple_normalize(substatus->account, - purple_contact_info_get_username(info)); - - purple_xmlnode_insert_data(child, name, -1); - - child = purple_xmlnode_new_child(node, "state"); - purple_xmlnode_insert_data(child, purple_status_type_get_id(substatus->type), -1); - - if (substatus->message != NULL) - { - child = purple_xmlnode_new_child(node, "message"); - purple_xmlnode_insert_data(child, substatus->message, -1); - } - - return node; -} - -static PurpleXmlNode * -status_to_xmlnode(PurpleSavedStatus *status) -{ - PurpleXmlNode *node, *child; - char buf[21]; - GList *cur; - - node = purple_xmlnode_new("status"); - if (status->title != NULL) - { - purple_xmlnode_set_attrib(node, "name", status->title); - } - else - { - /* - * Purple 1.5.0 and earlier require a name to be set, so we - * do this little hack to maintain backward compatibility - * in the status.xml file. Eventually this should be removed - * and we should determine if a status is transient by - * whether the "name" attribute is set to something or if - * it does not exist at all. - */ - purple_xmlnode_set_attrib(node, "name", "Auto-Cached"); - purple_xmlnode_set_attrib(node, "transient", "true"); - } - - g_snprintf(buf, sizeof(buf), "%" G_GINT64_FORMAT, - (gint64)status->creation_time); - purple_xmlnode_set_attrib(node, "created", buf); - - g_snprintf(buf, sizeof(buf), "%" G_GINT64_FORMAT, (gint64)status->lastused); - purple_xmlnode_set_attrib(node, "lastused", buf); - - g_snprintf(buf, sizeof(buf), "%u", status->usage_count); - purple_xmlnode_set_attrib(node, "usage_count", buf); - - child = purple_xmlnode_new_child(node, "state"); - purple_xmlnode_insert_data(child, purple_primitive_get_id_from_type(status->type), -1); - - if (status->message != NULL) - { - child = purple_xmlnode_new_child(node, "message"); - purple_xmlnode_insert_data(child, status->message, -1); - } - - for (cur = status->substatuses; cur != NULL; cur = cur->next) - { - child = substatus_to_xmlnode(cur->data); - purple_xmlnode_insert_child(node, child); - } - - return node; -} - -static PurpleXmlNode * -statuses_to_xmlnode(void) -{ - PurpleXmlNode *node, *child; - GList *cur; - - node = purple_xmlnode_new("statuses"); - purple_xmlnode_set_attrib(node, "version", "1.0"); - - for (cur = saved_statuses; cur != NULL; cur = cur->next) - { - child = status_to_xmlnode(cur->data); - purple_xmlnode_insert_child(node, child); - } - - return node; -} - -static void -sync_statuses(void) -{ - PurpleXmlNode *node; - char *data; - - if (!statuses_loaded) - { - purple_debug_error("status", "Attempted to save statuses before they " - "were read!\n"); - return; - } - - node = statuses_to_xmlnode(); - data = purple_xmlnode_to_formatted_str(node, NULL); - purple_util_write_data_to_config_file("status.xml", data, -1); - g_free(data); - purple_xmlnode_free(node); -} - -static gboolean -save_cb(G_GNUC_UNUSED gpointer data) -{ - sync_statuses(); - save_timer = 0; - return FALSE; -} - -static void -schedule_save(void) -{ - if (save_timer == 0) - save_timer = g_timeout_add_seconds(5, save_cb, NULL); -} - - -/********************************************************************* - * Reading from disk * - *********************************************************************/ - -static PurpleSavedStatusSub * -parse_substatus(PurpleXmlNode *substatus) -{ - PurpleSavedStatusSub *ret; - PurpleXmlNode *node; - char *data; - - ret = g_new0(PurpleSavedStatusSub, 1); - - /* Read the account */ - node = purple_xmlnode_get_child(substatus, "account"); - if(node != NULL) { - gchar *acct_name; - const char *protocol; - - acct_name = purple_xmlnode_get_data(node); - protocol = purple_xmlnode_get_attrib(node, "protocol"); - - if(acct_name != NULL && protocol != NULL) { - PurpleAccountManager *manager = NULL; - - manager = purple_account_manager_get_default(); - - ret->account = purple_account_manager_find(manager, acct_name, - protocol); - } - - g_free(acct_name); - } - - if(ret->account == NULL) { - free_saved_status_sub(ret); - return NULL; - } - - /* Read the state */ - node = purple_xmlnode_get_child(substatus, "state"); - if((node != NULL) && ((data = purple_xmlnode_get_data(node)) != NULL)) { - ret->type = purple_status_type_find_with_id( - purple_account_get_status_types(ret->account), data); - g_free(data); - } - - if(ret->type == NULL) { - free_saved_status_sub(ret); - return NULL; - } - - /* Read the message */ - node = purple_xmlnode_get_child(substatus, "message"); - if((node != NULL) && ((data = purple_xmlnode_get_data(node)) != NULL)) { - ret->message = data; - } - - return ret; -} - -/* - * Parse a saved status and add it to the saved_statuses linked list. - * - * Here's an example of the XML for a saved status: - * <status name="Girls"> - * <state>away</state> - * <message>I like the way that they walk - * And it's chill to hear them talk - * And I can always make them smile - * From White Castle to the Nile</message> - * <substatus> - * <account protocol='aim'>markdoliner</account> - * <state>available</state> - * <message>The ladies man is here to answer your queries.</message> - * </substatus> - * <substatus> - * <account protocol='aim'>giantgraypanda</account> - * <state>away</state> - * <message>A.C. ain't in charge no more.</message> - * </substatus> - * </status> - * - * I know. Moving, huh? - */ -static PurpleSavedStatus * -parse_status(PurpleXmlNode *status) -{ - PurpleSavedStatus *ret; - PurpleXmlNode *node; - const char *attrib; - char *data; - int i; - - ret = g_new0(PurpleSavedStatus, 1); - - attrib = purple_xmlnode_get_attrib(status, "transient"); - if (!purple_strequal(attrib, "true")) - { - /* Read the title */ - attrib = purple_xmlnode_get_attrib(status, "name"); - ret->title = g_strdup(attrib); - } - - if (ret->title != NULL) - { - /* Ensure the title is unique */ - i = 2; - while (purple_savedstatus_find(ret->title) != NULL) - { - g_free(ret->title); - ret->title = g_strdup_printf("%s %d", attrib, i); - i++; - } - } - - /* Read the creation time */ - attrib = purple_xmlnode_get_attrib(status, "created"); - set_creation_time(ret, - (attrib != NULL ? g_ascii_strtoll(attrib, NULL, 10) : 0)); - - /* Read the last used time */ - attrib = purple_xmlnode_get_attrib(status, "lastused"); - ret->lastused = (attrib != NULL ? g_ascii_strtoll(attrib, NULL, 10) : 0); - - /* Read the usage count */ - attrib = purple_xmlnode_get_attrib(status, "usage_count"); - ret->usage_count = (attrib != NULL ? atol(attrib) : 0); - - /* Read the primitive status type */ - node = purple_xmlnode_get_child(status, "state"); - if ((node != NULL) && ((data = purple_xmlnode_get_data(node)) != NULL)) - { - ret->type = purple_primitive_get_type_from_id(data); - g_free(data); - } - - /* Read the message */ - node = purple_xmlnode_get_child(status, "message"); - if ((node != NULL) && ((data = purple_xmlnode_get_data(node)) != NULL)) - { - ret->message = data; - } - - /* Read substatuses */ - for (node = purple_xmlnode_get_child(status, "substatus"); node != NULL; - node = purple_xmlnode_get_next_twin(node)) - { - PurpleSavedStatusSub *new; - new = parse_substatus(node); - if (new != NULL) - ret->substatuses = g_list_prepend(ret->substatuses, new); - } - - return ret; -} - -/* - * load_statuses: - * - * Read the saved statuses from a file in the Purple user dir. - * - * Returns: TRUE on success, FALSE on failure (if the file can not - * be opened, or if it contains invalid XML). - */ -static void -load_statuses(void) -{ - PurpleXmlNode *statuses, *status; - - statuses_loaded = TRUE; - - statuses = purple_util_read_xml_from_config_file("status.xml", _("saved statuses")); - - if (statuses == NULL) - return; - - for (status = purple_xmlnode_get_child(statuses, "status"); status != NULL; - status = purple_xmlnode_get_next_twin(status)) - { - PurpleSavedStatus *new; - new = parse_status(status); - saved_statuses = g_list_prepend(saved_statuses, new); - } - saved_statuses = g_list_sort(saved_statuses, saved_statuses_sort_func); - - purple_xmlnode_free(statuses); -} - - -/************************************************************************** -* Saved status API -**************************************************************************/ -PurpleSavedStatus * -purple_savedstatus_new(const char *title, PurpleStatusPrimitive type) -{ - PurpleSavedStatus *status; - - /* Make sure we don't already have a saved status with this title. */ - if (title != NULL) - g_return_val_if_fail(purple_savedstatus_find(title) == NULL, NULL); - - status = g_new0(PurpleSavedStatus, 1); - status->title = g_strdup(title); - status->type = type; - set_creation_time(status, time(NULL)); - - saved_statuses = g_list_insert_sorted(saved_statuses, status, saved_statuses_sort_func); - - schedule_save(); - - purple_signal_emit(purple_savedstatuses_get_handle(), "savedstatus-added", - status); - - return status; -} - -void -purple_savedstatus_set_title(PurpleSavedStatus *status, const char *title) -{ - g_return_if_fail(status != NULL); - - /* Make sure we don't already have a saved status with this title. */ - g_return_if_fail(purple_savedstatus_find(title) == NULL); - - g_free(status->title); - status->title = g_strdup(title); - - schedule_save(); - - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-modified", status); -} - -void -purple_savedstatus_set_primitive_type(PurpleSavedStatus *status, PurpleStatusPrimitive type) -{ - g_return_if_fail(status != NULL); - - status->type = type; - - schedule_save(); - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-modified", status); -} - -void -purple_savedstatus_set_message(PurpleSavedStatus *status, const char *message) -{ - g_return_if_fail(status != NULL); - - g_free(status->message); - if ((message != NULL) && (*message == '\0')) - status->message = NULL; - else - status->message = g_strdup(message); - - schedule_save(); - - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-modified", status); -} - -void -purple_savedstatus_set_substatus(PurpleSavedStatus *saved_status, - const PurpleAccount *account, - const PurpleStatusType *type, - const char *message) -{ - PurpleSavedStatusSub *substatus; - - g_return_if_fail(saved_status != NULL); - g_return_if_fail(account != NULL); - g_return_if_fail(type != NULL); - - /* Find an existing substatus or create a new one */ - substatus = purple_savedstatus_get_substatus(saved_status, account); - if (substatus == NULL) - { - substatus = g_new0(PurpleSavedStatusSub, 1); - substatus->account = (PurpleAccount *)account; - saved_status->substatuses = g_list_prepend(saved_status->substatuses, substatus); - } - - substatus->type = type; - g_free(substatus->message); - substatus->message = g_strdup(message); - - schedule_save(); - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-modified", saved_status); -} - -void -purple_savedstatus_unset_substatus(PurpleSavedStatus *saved_status, - const PurpleAccount *account) -{ - GList *iter; - PurpleSavedStatusSub *substatus; - - g_return_if_fail(saved_status != NULL); - g_return_if_fail(account != NULL); - - for (iter = saved_status->substatuses; iter != NULL; iter = iter->next) - { - substatus = iter->data; - if (substatus->account == account) - { - saved_status->substatuses = g_list_delete_link(saved_status->substatuses, iter); - free_saved_status_sub(substatus); - return; - } - } - - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-modified", saved_status); -} - -/* - * This gets called when an account is deleted. We iterate through - * all of our saved statuses and delete any substatuses that may - * exist for this account. - */ -static void -purple_savedstatus_unset_all_substatuses(G_GNUC_UNUSED PurpleAccountManager *manager, - PurpleAccount *account, - G_GNUC_UNUSED gpointer data) -{ - g_return_if_fail(account != NULL); - - g_list_foreach(saved_statuses, (GFunc)purple_savedstatus_unset_substatus, account); -} - -void -purple_savedstatus_delete_by_status(PurpleSavedStatus *status) -{ - time_t creation_time, current, idleaway; - - g_return_if_fail(status != NULL); - - saved_statuses = g_list_remove(saved_statuses, status); - creation_time = purple_savedstatus_get_creation_time(status); - g_hash_table_remove(creation_times, (gconstpointer)creation_time); - - schedule_save(); - - /* - * If we just deleted our current status or our idleaway status, - * then set the appropriate pref back to 0. - */ - current = purple_prefs_get_int("/purple/savedstatus/default"); - if (current == creation_time) - purple_prefs_set_int("/purple/savedstatus/default", 0); - - idleaway = purple_prefs_get_int("/purple/savedstatus/idleaway"); - if (idleaway == creation_time) - purple_prefs_set_int("/purple/savedstatus/idleaway", 0); - - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-deleted", status); - - free_saved_status(status); -} - -gboolean -purple_savedstatus_delete(const char *title) -{ - PurpleSavedStatus *status; - - status = purple_savedstatus_find(title); - - if (status == NULL) - return FALSE; - - if (purple_savedstatus_get_current() == status) - return FALSE; - - purple_savedstatus_delete_by_status(status); - - return TRUE; -} - -GList * -purple_savedstatuses_get_all(void) -{ - return saved_statuses; -} - -GList * -purple_savedstatuses_get_popular(unsigned int how_many) -{ - GList *popular = NULL; - GList *cur; - unsigned int i; - PurpleSavedStatus *next; - - /* Copy 'how_many' elements to a new list. If 'how_many' is 0, then copy all of 'em. */ - if (how_many == 0) - how_many = (unsigned int) -1; - - i = 0; - cur = saved_statuses; - while ((i < how_many) && (cur != NULL)) - { - next = cur->data; - if ((!purple_savedstatus_is_transient(next) - || purple_savedstatus_get_message(next) != NULL)) - { - popular = g_list_prepend(popular, next); - i++; - } - cur = cur->next; - } - - popular = g_list_reverse(popular); - - return popular; -} - -PurpleSavedStatus * -purple_savedstatus_get_current(void) -{ - if (purple_savedstatus_is_idleaway()) - return purple_savedstatus_get_idleaway(); - else - return purple_savedstatus_get_default(); -} - -PurpleSavedStatus * -purple_savedstatus_get_default(void) -{ - time_t creation_time; - PurpleSavedStatus *saved_status = NULL; - - creation_time = purple_prefs_get_int("/purple/savedstatus/default"); - - if (creation_time != 0) - saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time); - - if (saved_status == NULL) - { - /* - * We don't have a current saved status! This is either a new - * Purple user or someone upgrading from Purple 1.5.0 or older, or - * possibly someone who deleted the status they were currently - * using? In any case, add a default status. - */ - saved_status = purple_savedstatus_new(NULL, PURPLE_STATUS_AVAILABLE); - purple_prefs_set_int("/purple/savedstatus/default", - purple_savedstatus_get_creation_time(saved_status)); - } - - return saved_status; -} - -PurpleSavedStatus * -purple_savedstatus_get_idleaway(void) -{ - time_t creation_time; - PurpleSavedStatus *saved_status = NULL; - - creation_time = purple_prefs_get_int("/purple/savedstatus/idleaway"); - - if (creation_time != 0) - saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time); - - if (saved_status == NULL) - { - /* We don't have a specified "idle" status! Weird. */ - saved_status = purple_savedstatus_find_transient_by_type_and_message( - PURPLE_STATUS_AWAY, DEFAULT_AUTOAWAY_MESSAGE); - - if (saved_status == NULL) - { - saved_status = purple_savedstatus_new(NULL, PURPLE_STATUS_AWAY); - purple_savedstatus_set_message(saved_status, DEFAULT_AUTOAWAY_MESSAGE); - purple_prefs_set_int("/purple/savedstatus/idleaway", - purple_savedstatus_get_creation_time(saved_status)); - } - } - - return saved_status; -} - -gboolean -purple_savedstatus_is_idleaway(void) -{ - return purple_prefs_get_bool("/purple/savedstatus/isidleaway"); -} - -void -purple_savedstatus_set_idleaway(gboolean idleaway) { - PurpleAccountManager *manager = NULL; - PurpleSavedStatus *old, *saved_status; - GList *accounts, *node; - - if(purple_savedstatus_is_idleaway() == idleaway) { - /* Don't need to do anything */ - return; - } - - old = purple_savedstatus_get_current(); - saved_status = idleaway ? purple_savedstatus_get_idleaway() - : purple_savedstatus_get_default(); - purple_prefs_set_bool("/purple/savedstatus/isidleaway", idleaway); - - if(idleaway && (purple_savedstatus_get_primitive_type(old) != PURPLE_STATUS_AVAILABLE)) - { - /* Our global status is already "away," so don't change anything */ - return; - } - - manager = purple_account_manager_get_default(); - accounts = purple_account_manager_get_enabled(manager); - for (node = accounts; node != NULL; node = node->next) { - PurpleAccount *account; - PurplePresence *presence; - PurpleStatus *status; - - account = node->data; - presence = purple_account_get_presence(account); - status = purple_presence_get_active_status(presence); - - if (!idleaway || purple_status_is_available(status)) - purple_savedstatus_activate_for_account(saved_status, account); - } - - g_list_free(accounts); - - purple_signal_emit(purple_savedstatuses_get_handle(), "savedstatus-changed", - saved_status, old); -} - -PurpleSavedStatus * -purple_savedstatus_get_startup(void) -{ - time_t creation_time; - PurpleSavedStatus *saved_status = NULL; - - creation_time = purple_prefs_get_int("/purple/savedstatus/startup"); - - if (creation_time != 0) - saved_status = g_hash_table_lookup(creation_times, (gconstpointer)creation_time); - - if (saved_status == NULL) - { - /* - * We don't have a status to apply. - * This may be the first login, or the user wants to - * restore the "current" status. - */ - saved_status = purple_savedstatus_get_current(); - } - - return saved_status; -} - - -PurpleSavedStatus * -purple_savedstatus_find(const char *title) -{ - GList *iter; - PurpleSavedStatus *status; - - g_return_val_if_fail(title != NULL, NULL); - - for (iter = saved_statuses; iter != NULL; iter = iter->next) - { - status = (PurpleSavedStatus *)iter->data; - if (purple_strequal(status->title, title)) - return status; - } - - return NULL; -} - -PurpleSavedStatus * -purple_savedstatus_find_by_creation_time(time_t creation_time) -{ - GList *iter; - PurpleSavedStatus *status; - - for (iter = saved_statuses; iter != NULL; iter = iter->next) - { - status = (PurpleSavedStatus *)iter->data; - if (status->creation_time == creation_time) - return status; - } - - return NULL; -} - -PurpleSavedStatus * -purple_savedstatus_find_transient_by_type_and_message(PurpleStatusPrimitive type, - const char *message) -{ - GList *iter; - PurpleSavedStatus *status; - - for (iter = saved_statuses; iter != NULL; iter = iter->next) - { - status = (PurpleSavedStatus *)iter->data; - if ((status->type == type) && purple_savedstatus_is_transient(status) && - !purple_savedstatus_has_substatuses(status) && - purple_strequal(status->message, message)) - { - return status; - } - } - - return NULL; -} - -gboolean -purple_savedstatus_is_transient(const PurpleSavedStatus *saved_status) -{ - g_return_val_if_fail(saved_status != NULL, TRUE); - - return (saved_status->title == NULL); -} - -const char * -purple_savedstatus_get_title(const PurpleSavedStatus *saved_status) -{ - const char *message; - - g_return_val_if_fail(saved_status != NULL, NULL); - - /* If we have a title then return it */ - if (saved_status->title != NULL) - return saved_status->title; - - /* Otherwise, this is a transient status and we make up a title on the fly */ - message = purple_savedstatus_get_message(saved_status); - - if ((message == NULL) || (*message == '\0')) - { - PurpleStatusPrimitive primitive; - primitive = purple_savedstatus_get_primitive_type(saved_status); - return purple_primitive_get_name_from_type(primitive); - } - else - { - char *stripped; - static char buf[64]; - stripped = purple_markup_strip_html(message); - purple_util_chrreplace(stripped, '\n', ' '); - strncpy(buf, stripped, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - if ((strlen(stripped) + 1) > sizeof(buf)) - { - /* Truncate and ellipsize */ - char *tmp = g_utf8_find_prev_char(buf, &buf[sizeof(buf) - 4]); - strcpy(tmp, "..."); - } - g_free(stripped); - return buf; - } -} - -PurpleStatusPrimitive -purple_savedstatus_get_primitive_type(const PurpleSavedStatus *saved_status) -{ - g_return_val_if_fail(saved_status != NULL, PURPLE_STATUS_OFFLINE); - - return saved_status->type; -} - -const char * -purple_savedstatus_get_message(const PurpleSavedStatus *saved_status) -{ - g_return_val_if_fail(saved_status != NULL, NULL); - - return saved_status->message; -} - -time_t -purple_savedstatus_get_creation_time(const PurpleSavedStatus *saved_status) -{ - g_return_val_if_fail(saved_status != NULL, 0); - - return saved_status->creation_time; -} - -gboolean -purple_savedstatus_has_substatuses(const PurpleSavedStatus *saved_status) -{ - g_return_val_if_fail(saved_status != NULL, FALSE); - - return (saved_status->substatuses != NULL); -} - -PurpleSavedStatusSub * -purple_savedstatus_get_substatus(const PurpleSavedStatus *saved_status, - const PurpleAccount *account) -{ - GList *iter; - PurpleSavedStatusSub *substatus; - - g_return_val_if_fail(saved_status != NULL, NULL); - g_return_val_if_fail(account != NULL, NULL); - - for (iter = saved_status->substatuses; iter != NULL; iter = iter->next) - { - substatus = iter->data; - if (substatus->account == account) - return substatus; - } - - return NULL; -} - -const PurpleStatusType * -purple_savedstatus_substatus_get_status_type(const PurpleSavedStatusSub *substatus) -{ - g_return_val_if_fail(substatus != NULL, NULL); - - return substatus->type; -} - -const char * -purple_savedstatus_substatus_get_message(const PurpleSavedStatusSub *substatus) -{ - g_return_val_if_fail(substatus != NULL, NULL); - - return substatus->message; -} - -void -purple_savedstatus_activate(PurpleSavedStatus *saved_status) { - PurpleAccountManager *manager = NULL; - PurpleSavedStatus *old = purple_savedstatus_get_current(); - GList *accounts, *node; - - g_return_if_fail(saved_status != NULL); - - /* Make sure our list of saved statuses remains sorted */ - saved_status->lastused = time(NULL); - saved_status->usage_count++; - saved_statuses = g_list_remove(saved_statuses, saved_status); - saved_statuses = g_list_insert_sorted(saved_statuses, saved_status, - saved_statuses_sort_func); - purple_prefs_set_int("/purple/savedstatus/default", - purple_savedstatus_get_creation_time(saved_status)); - - manager = purple_account_manager_get_default(); - accounts = purple_account_manager_get_enabled(manager); - for(node = accounts; node != NULL; node = node->next) { - PurpleAccount *account; - - account = node->data; - - purple_savedstatus_activate_for_account(saved_status, account); - } - - g_list_free(accounts); - - if(purple_savedstatus_is_idleaway()) { - purple_savedstatus_set_idleaway(FALSE); - } else { - purple_signal_emit(purple_savedstatuses_get_handle(), - "savedstatus-changed", saved_status, old); - } -} - -void -purple_savedstatus_activate_for_account(const PurpleSavedStatus *saved_status, - PurpleAccount *account) -{ - const PurpleStatusType *status_type; - const PurpleSavedStatusSub *substatus; - const char *message = NULL; - - g_return_if_fail(saved_status != NULL); - g_return_if_fail(account != NULL); - - substatus = purple_savedstatus_get_substatus(saved_status, account); - if (substatus != NULL) - { - status_type = substatus->type; - message = substatus->message; - } - else - { - status_type = purple_account_get_status_type_with_primitive(account, saved_status->type); - if (status_type == NULL) - return; - message = saved_status->message; - } - - if ((message != NULL) && - (purple_status_type_get_attr(status_type, "message"))) - { - purple_account_set_status(account, purple_status_type_get_id(status_type), - TRUE, "message", message, NULL); - } - else - { - purple_account_set_status(account, purple_status_type_get_id(status_type), - TRUE, NULL); - } -} - -static PurpleSavedStatus * -purple_savedstatus_copy(PurpleSavedStatus *savedstatus) -{ - PurpleSavedStatus *savedstatus_copy; - - g_return_val_if_fail(savedstatus != NULL, NULL); - - savedstatus_copy = g_new(PurpleSavedStatus, 1); - *savedstatus_copy = *savedstatus; - - return savedstatus_copy; -} - -GType -purple_savedstatus_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - type = g_boxed_type_register_static("PurpleSavedStatus", - (GBoxedCopyFunc)purple_savedstatus_copy, - (GBoxedFreeFunc)g_free); - } - - return type; -} - -void * -purple_savedstatuses_get_handle(void) -{ - static int handle; - - return &handle; -} - -void -purple_savedstatuses_init(void) -{ - PurpleAccountManager *manager = purple_account_manager_get_default(); - void *handle = purple_savedstatuses_get_handle(); - - creation_times = g_hash_table_new(g_direct_hash, g_direct_equal); - - /* - * Using 0 as the creation_time is a special case. - * If someone calls purple_savedstatus_get_current() or - * purple_savedstatus_get_idleaway() and either of those functions - * sees a creation_time of 0, then it will create a default - * saved status and return that to the user. - */ - purple_prefs_add_none("/purple/savedstatus"); - purple_prefs_add_int("/purple/savedstatus/default", 0); - purple_prefs_add_int("/purple/savedstatus/startup", 0); - purple_prefs_add_bool("/purple/savedstatus/startup_current_status", TRUE); - purple_prefs_add_int("/purple/savedstatus/idleaway", 0); - purple_prefs_add_bool("/purple/savedstatus/isidleaway", FALSE); - - load_statuses(); - - purple_signal_register(handle, "savedstatus-changed", - purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2, - PURPLE_TYPE_SAVEDSTATUS, PURPLE_TYPE_SAVEDSTATUS); - - purple_signal_register(handle, "savedstatus-added", - purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, - PURPLE_TYPE_SAVEDSTATUS); - - purple_signal_register(handle, "savedstatus-deleted", - purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, - PURPLE_TYPE_SAVEDSTATUS); - - purple_signal_register(handle, "savedstatus-modified", - purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, - PURPLE_TYPE_SAVEDSTATUS); - - g_signal_connect(manager, "removed", - G_CALLBACK(purple_savedstatus_unset_all_substatuses), - NULL); -} - -void -purple_savedstatuses_uninit(void) -{ - PurpleAccountManager *manager = purple_account_manager_get_default(); - gpointer handle = purple_savedstatuses_get_handle(); - - remove_old_transient_statuses(); - - if(save_timer != 0) { - g_clear_handle_id(&save_timer, g_source_remove); - sync_statuses(); - } - - g_clear_list(&saved_statuses, (GDestroyNotify)free_saved_status); - - g_clear_pointer(&creation_times, g_hash_table_destroy); - - g_signal_handlers_disconnect_by_func(manager, - purple_savedstatus_unset_all_substatuses, - NULL); - purple_signals_unregister_by_instance(handle); - purple_signals_disconnect_by_handle(handle); -}
--- a/libpurple/savedstatuses.h Fri Apr 12 01:55:22 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,574 +0,0 @@ -/* - * Purple - Internet Messaging Library - * 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 library 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 library 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 library; 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_SAVEDSTATUSES_H -#define PURPLE_SAVEDSTATUSES_H - -#define PURPLE_TYPE_SAVEDSTATUS (purple_savedstatus_get_type()) - -/** - * PurpleSavedStatus: - * - * Saved statuses don't really interact much with the rest of Purple. It - * could really be a plugin. It's just a list of away states. When - * a user chooses one of the saved states, their Purple accounts are set - * to the settings of that state. - * - * In the savedstatus API, there is the concept of a 'transient' - * saved status. A transient saved status is one that is not - * permanent. Purple will removed it automatically if it isn't - * used for a period of time. Transient saved statuses don't - * have titles and they don't show up in the list of saved - * statuses. In fact, if a saved status does not have a title - * then it is transient. If it does have a title, then it is not - * transient. - * - * What good is a transient status, you ask? They can be used to - * keep track of the user's 5 most recently used statuses, for - * example. Basically if they just set a message on the fly, - * we'll cache it for them in case they want to use it again. If - * they don't use it again, we'll just delete it. - * - * Since: 2.0 - */ -/* - * TODO: Hmm. We should probably just be saving PurplePresences. That's - * something we should look into once the status box gets fleshed - * out more. - */ -typedef struct _PurpleSavedStatus PurpleSavedStatus; - -/** - * PurpleSavedStatusSub: - * - * A sub statuses of a saved status. - * - * Since: 2.0 - */ -typedef struct _PurpleSavedStatusSub PurpleSavedStatusSub; - -#include "status.h" -#include "purpleversion.h" - -G_BEGIN_DECLS - -/**************************************************************************/ -/* Saved status subsystem */ -/**************************************************************************/ - -/** - * purple_savedstatus_get_type: - * - * The standard _get_type function for #PurpleSavedStatus. - * - * Returns: The #GType for the #PurpleSavedStatus boxed structure. - */ -/* TODO Boxing of PurpleSavedStatus is a temporary solution to having a GType - * for saved statuses. This should rather be a GObject instead of a GBoxed. - */ -PURPLE_AVAILABLE_IN_3_0 -GType purple_savedstatus_get_type(void); - -/** - * purple_savedstatus_new: - * @title: The title of the saved status. This must be - * unique. Or, if you want to create a transient - * saved status, then pass in NULL. - * @type: The type of saved status. - * - * Create a new saved status. This will add the saved status to the - * list of saved statuses and writes the revised list to status.xml. - * - * Returns: The newly created saved status, or NULL if the title you - * used was already taken. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_new(const char *title, PurpleStatusPrimitive type); - -/** - * purple_savedstatus_set_title: - * @status: The saved status. - * @title: The title of the saved status. - * - * Set the title for the given saved status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_set_title(PurpleSavedStatus *status, const char *title); - -/** - * purple_savedstatus_set_primitive_type: - * @status: The saved status. - * @type: The type of saved status. - * - * Set the type for the given saved status. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_savedstatus_set_primitive_type(PurpleSavedStatus *status, PurpleStatusPrimitive type); - -/** - * purple_savedstatus_set_message: - * @status: The saved status. - * @message: The message, or NULL if you want to unset the - * message for this status. - * - * Set the message for the given saved status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_set_message(PurpleSavedStatus *status, const char *message); - -/** - * purple_savedstatus_set_substatus: - * @status: The saved status. - * @account: The account. - * @type: The status type for the account in the saved - * status. - * @message: The message for the account in the substatus. - * - * Set a substatus for an account in a saved status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_set_substatus(PurpleSavedStatus *status, const PurpleAccount *account, const PurpleStatusType *type, const char *message); - -/** - * purple_savedstatus_unset_substatus: - * @saved_status: The saved status. - * @account: The account. - * - * Unset a substatus for an account in a saved status. This clears - * the previously set substatus for the PurpleSavedStatus. If this - * saved status is activated then this account will use the default - * status type and message. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_unset_substatus(PurpleSavedStatus *saved_status, const PurpleAccount *account); - -/** - * purple_savedstatus_delete: - * @title: The title of the saved status. - * - * Delete a saved status. This removes the saved status from the list - * of saved statuses, and writes the revised list to status.xml. - * - * Returns: TRUE if the status was successfully deleted. FALSE if the - * status could not be deleted because no saved status exists - * with the given title. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_savedstatus_delete(const char *title); - -/** - * purple_savedstatus_delete_by_status: - * @saved_status: the status to delete, the pointer is invalid after - * the call - * - * Delete a saved status. This removes the saved status from the list - * of saved statuses, and writes the revised list to status.xml. - * - * Since: 2.1 - */ -PURPLE_AVAILABLE_IN_2_1 -void purple_savedstatus_delete_by_status(PurpleSavedStatus *saved_status); - -/** - * purple_savedstatuses_get_all: - * - * Returns all saved statuses. - * - * Returns: (element-type PurpleSavedStatus) (transfer none): A list of saved - * statuses. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GList *purple_savedstatuses_get_all(void); - -/** - * purple_savedstatuses_get_popular: - * @how_many: The maximum number of saved statuses - * to return, or '0' to get all saved - * statuses sorted by popularity. - * - * Returns the n most popular saved statuses. "Popularity" is - * determined by when the last time a saved_status was used and - * how many times it has been used. Transient statuses without - * messages are not included in the list. - * - * Returns: (element-type PurpleSavedStatus) (transfer container): A list containing - * at most how_many saved statuses. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GList *purple_savedstatuses_get_popular(unsigned int how_many); - -/** - * purple_savedstatus_get_current: - * - * Returns the currently selected saved status. If we are idle - * then this returns purple_savedstatus_get_idleaway(). Otherwise - * it returns purple_savedstatus_get_default(). - * - * Returns: A pointer to the in-use PurpleSavedStatus. - * This function never returns NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_get_current(void); - -/** - * purple_savedstatus_get_default: - * - * Returns the default saved status that is used when our - * accounts are not idle-away. - * - * Returns: A pointer to the in-use PurpleSavedStatus. - * This function never returns NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_get_default(void); - -/** - * purple_savedstatus_get_idleaway: - * - * Returns the saved status that is used when your - * accounts become idle-away. - * - * Returns: A pointer to the idle-away PurpleSavedStatus. - * This function never returns NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_get_idleaway(void); - -/** - * purple_savedstatus_is_idleaway: - * - * Return TRUE if we are currently idle-away. Otherwise - * returns FALSE. - * - * Returns: TRUE if our accounts have been set to idle-away. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_savedstatus_is_idleaway(void); - -/** - * purple_savedstatus_set_idleaway: - * @idleaway: TRUE if accounts should be switched to use the - * idle-away saved status. FALSE if they should - * be switched to use the default status. - * - * Set whether accounts in Purple are idle-away or not. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_set_idleaway(gboolean idleaway); - -/** - * purple_savedstatus_get_startup: - * - * Returns the status to be used when purple is starting up - * - * Returns: A pointer to the startup PurpleSavedStatus. - * This function never returns NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_get_startup(void); - -/** - * purple_savedstatus_find: - * @title: The name of the saved status. - * - * Finds a saved status with the specified title. - * - * Returns: The saved status if found, or NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_find(const char *title); - -/** - * purple_savedstatus_find_by_creation_time: - * @creation_time: The timestamp when the saved - * status was created. - * - * Finds a saved status with the specified creation time. - * - * Returns: The saved status if found, or NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_find_by_creation_time(time_t creation_time); - -/** - * purple_savedstatus_find_transient_by_type_and_message: - * @type: The PurpleStatusPrimitive for the status you're trying - * to find. - * @message: The message for the status you're trying - * to find. - * - * Finds a saved status with the specified primitive and message. - * - * Returns: The saved status if found, or NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatus *purple_savedstatus_find_transient_by_type_and_message(PurpleStatusPrimitive type, const char *message); - -/** - * purple_savedstatus_is_transient: - * @saved_status: The saved status. - * - * Determines if a given saved status is "transient." - * A transient saved status is one that was not - * explicitly added by the user. Transient statuses - * are automatically removed if they are not used - * for a period of time. - * - * A transient saved statuses is automatically - * created by the status box when the user sets himself - * to one of the generic primitive statuses. The reason - * we need to save this status information is so we can - * restore it when Purple restarts. - * - * Returns: TRUE if the saved status is transient. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_savedstatus_is_transient(const PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_get_title: - * @saved_status: The saved status. - * - * Return the name of a given saved status. - * - * Returns: The title. This value may be a static buffer which may - * be overwritten on subsequent calls to this function. If - * you need a reference to the title for prolonged use then - * you should make a copy of it. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_savedstatus_get_title(const PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_get_primitive_type: - * @saved_status: The saved status. - * - * Return the type of a given saved status. - * - * Returns: The primitive type. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleStatusPrimitive purple_savedstatus_get_primitive_type(const PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_get_message: - * @saved_status: The saved status. - * - * Return the default message of a given saved status. - * - * Returns: The message. This will return NULL if the saved - * status does not have a message. This will - * contain the normal markup that is created by - * Purple's IMHTML (basically HTML markup). - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_savedstatus_get_message(const PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_get_creation_time: - * @saved_status: The saved status. - * - * Return the time in seconds-since-the-epoch when this - * saved status was created. Note: For any status created - * by Purple 1.5.0 or older this value will be invalid and - * very small (close to 0). This is because Purple 1.5.0 - * and older did not record the timestamp when the status - * was created. - * - * However, this value is guaranteed to be a unique - * identifier for the given saved status. - * - * Returns: The timestamp when this saved status was created. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -time_t purple_savedstatus_get_creation_time(const PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_has_substatuses: - * @saved_status: The saved status. - * - * Determine if a given saved status has "substatuses," - * or if it is a simple status (the same for all - * accounts). - * - * Returns: TRUE if the saved_status has substatuses. - * FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_savedstatus_has_substatuses(const PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_get_substatus: - * @saved_status: The saved status. - * @account: The account. - * - * Get the substatus for an account in a saved status. - * - * Returns: (transfer none): The PurpleSavedStatusSub for the account, or NULL if - * the given account does not have a substatus that - * differs from the default status of this PurpleSavedStatus. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleSavedStatusSub *purple_savedstatus_get_substatus(const PurpleSavedStatus *saved_status, const PurpleAccount *account); - -/** - * purple_savedstatus_substatus_get_status_type: - * @substatus: The substatus. - * - * Get the status type of a given substatus. - * - * Returns: The status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const PurpleStatusType *purple_savedstatus_substatus_get_status_type(const PurpleSavedStatusSub *substatus); - -/** - * purple_savedstatus_substatus_get_message: - * @substatus: The substatus. - * - * Get the message of a given substatus. - * - * Returns: The message of the substatus, or NULL if this substatus does - * not have a message. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_savedstatus_substatus_get_message(const PurpleSavedStatusSub *substatus); - -/** - * purple_savedstatus_activate: - * @saved_status: The status you want to set your accounts to. - * - * Sets the statuses for all your accounts to those specified - * by the given saved_status. This function calls - * purple_savedstatus_activate_for_account() for all your accounts. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_activate(PurpleSavedStatus *saved_status); - -/** - * purple_savedstatus_activate_for_account: - * @saved_status: The status you want to set your accounts to. - * @account: The account whose statuses you want to change. - * - * Sets the statuses for a given account to those specified - * by the given saved_status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatus_activate_for_account(const PurpleSavedStatus *saved_status, PurpleAccount *account); - -/** - * purple_savedstatuses_get_handle: - * - * Get the handle for the status subsystem. - * - * Returns: the handle to the status subsystem - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void *purple_savedstatuses_get_handle(void); - -/** - * purple_savedstatuses_init: - * - * Initializes the status subsystem. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatuses_init(void); - -/** - * purple_savedstatuses_uninit: - * - * Uninitializes the status subsystem. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_savedstatuses_uninit(void); - -G_END_DECLS - -#endif /* PURPLE_SAVEDSTATUSES_H */
--- a/libpurple/server.c Fri Apr 12 01:55:22 2024 -0500 +++ b/libpurple/server.c Fri Apr 12 02:08:00 2024 -0500 @@ -39,7 +39,6 @@ #include "request.h" #include "signals.h" #include "server.h" -#include "status.h" #include "util.h" unsigned int
--- a/libpurple/status.c Fri Apr 12 01:55:22 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1248 +0,0 @@ -/* - * Purple - Internet Messaging Library - * 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 library 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 library 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 library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include <glib/gi18n-lib.h> - -#include "purpleprivate.h" - -#include "buddylist.h" -#include "core.h" -#include "debug.h" -#include "notify.h" -#include "prefs.h" -#include "status.h" - -/* - * A type of status. - */ -struct _PurpleStatusType -{ - int box_count; - - PurpleStatusPrimitive primitive; - - char *id; - char *name; - - gboolean saveable; - gboolean user_settable; - gboolean independent; - - GList *attrs; -}; - -/* - * A status attribute. - */ -struct _PurpleStatusAttribute -{ - char *id; - char *name; - GValue *value_type; -}; - -struct _PurpleStatus -{ - GObject parent; - - PurpleStatusType *status_type; - PurplePresence *presence; - - gboolean active; - - /* - * The current values of the attributes for this status. The - * key is a string containing the name of the attribute. It is - * a borrowed reference from the list of attrs in the - * PurpleStatusType. The value is a GValue. - */ - GHashTable *attr_values; -}; - -/* GObject property enums */ -enum -{ - PROP_0, - PROP_STATUS_TYPE, - PROP_PRESENCE, - PROP_ACTIVE, - N_PROPERTIES, -}; - -static GParamSpec *properties[N_PROPERTIES] = {NULL, }; - -G_DEFINE_FINAL_TYPE(PurpleStatus, purple_status, G_TYPE_OBJECT) - -static int primitive_scores[] = -{ - 0, /* unset */ - -500, /* offline */ - 100, /* available */ - -75, /* unavailable */ - -50, /* invisible */ - -100, /* away */ - -200, /* extended away */ - -400, /* mobile */ - -10, /* idle, special case. */ - -5, /* idle time, special case. */ - 10 /* Offline messageable */ -}; - -enum { - SCORE_IDLE = PURPLE_STATUS_NUM_PRIMITIVES, - SCORE_IDLE_TIME, - SCORE_OFFLINE_MESSAGE, -}; - -/************************************************************************** - * PurpleStatusPrimitive API - **************************************************************************/ -static struct PurpleStatusPrimitiveMap -{ - PurpleStatusPrimitive type; - const char *id; - const char *name; - -} const status_primitive_map[] = -{ - { PURPLE_STATUS_UNSET, "unset", N_("Unset") }, - { PURPLE_STATUS_OFFLINE, "offline", N_("Offline") }, - { PURPLE_STATUS_AVAILABLE, "available", N_("Available") }, - { PURPLE_STATUS_UNAVAILABLE, "unavailable", N_("Do not disturb") }, - { PURPLE_STATUS_INVISIBLE, "invisible", N_("Invisible") }, - { PURPLE_STATUS_AWAY, "away", N_("Away") }, - { PURPLE_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended away") }, - { PURPLE_STATUS_MOBILE, "mobile", N_("Mobile") }, -}; - -int * -_purple_statuses_get_primitive_scores(void) -{ - return primitive_scores; -} - -const char * -purple_primitive_get_id_from_type(PurpleStatusPrimitive type) -{ - int i; - - for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) - { - if (type == status_primitive_map[i].type) - return status_primitive_map[i].id; - } - - return status_primitive_map[0].id; -} - -const char * -purple_primitive_get_name_from_type(PurpleStatusPrimitive type) -{ - int i; - - for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) - { - if (type == status_primitive_map[i].type) - return _(status_primitive_map[i].name); - } - - return _(status_primitive_map[0].name); -} - -PurpleStatusPrimitive -purple_primitive_get_type_from_id(const char *id) -{ - int i; - - g_return_val_if_fail(id != NULL, PURPLE_STATUS_UNSET); - - for (i = 0; i < PURPLE_STATUS_NUM_PRIMITIVES; i++) - { - if (purple_strequal(id, status_primitive_map[i].id)) - return status_primitive_map[i].type; - } - - return status_primitive_map[0].type; -} - - -/************************************************************************** - * PurpleStatusType API - **************************************************************************/ -PurpleStatusType * -purple_status_type_new_full(PurpleStatusPrimitive primitive, const char *id, - const char *name, gboolean saveable, - gboolean user_settable, gboolean independent) -{ - PurpleStatusType *status_type; - - g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); - - status_type = g_new0(PurpleStatusType, 1); - - status_type->primitive = primitive; - status_type->saveable = saveable; - status_type->user_settable = user_settable; - status_type->independent = independent; - - if (id != NULL) - status_type->id = g_strdup(id); - else - status_type->id = g_strdup(purple_primitive_get_id_from_type(primitive)); - - if (name != NULL) - status_type->name = g_strdup(name); - else - status_type->name = g_strdup(purple_primitive_get_name_from_type(primitive)); - - return status_type; -} - -PurpleStatusType * -purple_status_type_new(PurpleStatusPrimitive primitive, const char *id, - const char *name, gboolean user_settable) -{ - g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); - - return purple_status_type_new_full(primitive, id, name, TRUE, - user_settable, FALSE); -} - -static void -status_type_add_attr(PurpleStatusType *status_type, const char *id, - const char *name, GValue *value) -{ - PurpleStatusAttribute *attr; - - g_return_if_fail(status_type != NULL); - g_return_if_fail(id != NULL); - g_return_if_fail(name != NULL); - g_return_if_fail(value != NULL); - - attr = purple_status_attribute_new(id, name, value); - - status_type->attrs = g_list_append(status_type->attrs, attr); -} - -static void -status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args) -{ - const char *id, *name; - GValue *value; - - g_return_if_fail(status_type != NULL); - - while ((id = va_arg(args, const char *)) != NULL) - { - name = va_arg(args, const char *); - g_return_if_fail(name != NULL); - - value = va_arg(args, GValue *); - g_return_if_fail(value != NULL); - - status_type_add_attr(status_type, id, name, value); - } -} - -PurpleStatusType * -purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive, - const char *id, const char *name, - gboolean saveable, gboolean user_settable, - gboolean independent, const char *attr_id, - const char *attr_name, GValue *attr_value, - ...) -{ - PurpleStatusType *status_type; - va_list args; - - g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); - g_return_val_if_fail(attr_id != NULL, NULL); - g_return_val_if_fail(attr_name != NULL, NULL); - g_return_val_if_fail(attr_value != NULL, NULL); - - status_type = purple_status_type_new_full(primitive, id, name, saveable, - user_settable, independent); - - /* Add the first attribute */ - status_type_add_attr(status_type, attr_id, attr_name, attr_value); - - va_start(args, attr_value); - status_type_add_attrs_vargs(status_type, args); - va_end(args); - - return status_type; -} - -PurpleStatusType * -purple_status_type_new_with_attrsv(PurpleStatusPrimitive primitive, - const char *id, const char *name, - gboolean saveable, gboolean user_settable, - gboolean independent, guint n_attributes, - const char *attr_id[], - const char *attr_name[], - GValue *attr_value[]) -{ - PurpleStatusType *status_type; - - g_return_val_if_fail(primitive != PURPLE_STATUS_UNSET, NULL); - g_return_val_if_fail(attr_id != NULL, NULL); - g_return_val_if_fail(attr_name != NULL, NULL); - g_return_val_if_fail(attr_value != NULL, NULL); - - status_type = purple_status_type_new_full(primitive, id, name, saveable, - user_settable, independent); - - for(guint i = 0; i < n_attributes; i++) { - if(attr_id[i] == NULL || attr_name[i] == NULL || - attr_value[i] == NULL) - { - purple_status_type_destroy(status_type); - g_return_val_if_fail(attr_id[i] != NULL, NULL); - g_return_val_if_fail(attr_name[i] != NULL, NULL); - g_return_val_if_fail(attr_value[i] != NULL, NULL); - return NULL; - } - - status_type_add_attr(status_type, attr_id[i], attr_name[i], - attr_value[i]); - } - - return status_type; -} - -void -purple_status_type_destroy(PurpleStatusType *status_type) -{ - g_return_if_fail(status_type != NULL); - - g_free(status_type->id); - g_free(status_type->name); - - g_list_free_full(status_type->attrs, - (GDestroyNotify)purple_status_attribute_destroy); - - g_free(status_type); -} - -PurpleStatusPrimitive -purple_status_type_get_primitive(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, PURPLE_STATUS_UNSET); - - return status_type->primitive; -} - -const char * -purple_status_type_get_id(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, NULL); - - return status_type->id; -} - -const char * -purple_status_type_get_name(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, NULL); - - return status_type->name; -} - -gboolean -purple_status_type_is_saveable(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, FALSE); - - return status_type->saveable; -} - -gboolean -purple_status_type_is_user_settable(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, FALSE); - - return status_type->user_settable; -} - -gboolean -purple_status_type_is_independent(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, FALSE); - - return status_type->independent; -} - -gboolean -purple_status_type_is_exclusive(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, FALSE); - - return !status_type->independent; -} - -gboolean -purple_status_type_is_available(const PurpleStatusType *status_type) -{ - PurpleStatusPrimitive primitive; - - g_return_val_if_fail(status_type != NULL, FALSE); - - primitive = purple_status_type_get_primitive(status_type); - - return (primitive == PURPLE_STATUS_AVAILABLE); -} - -PurpleStatusAttribute * -purple_status_type_get_attr(const PurpleStatusType *status_type, const char *id) -{ - GList *l; - - g_return_val_if_fail(status_type != NULL, NULL); - g_return_val_if_fail(id != NULL, NULL); - - for (l = status_type->attrs; l != NULL; l = l->next) - { - PurpleStatusAttribute *attr = (PurpleStatusAttribute *)l->data; - - if (purple_strequal(purple_status_attribute_get_id(attr), id)) - return attr; - } - - return NULL; -} - -GList * -purple_status_type_get_attrs(const PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, NULL); - - return status_type->attrs; -} - -const PurpleStatusType * -purple_status_type_find_with_id(GList *status_types, const char *id) -{ - PurpleStatusType *status_type; - - g_return_val_if_fail(id != NULL, NULL); - - while (status_types != NULL) - { - status_type = status_types->data; - - if (purple_strequal(id, status_type->id)) - return status_type; - - status_types = status_types->next; - } - - return NULL; -} - - -/************************************************************************** -* PurpleStatusAttribute API -**************************************************************************/ -PurpleStatusAttribute * -purple_status_attribute_new(const char *id, const char *name, GValue *value_type) -{ - PurpleStatusAttribute *attr; - - g_return_val_if_fail(id != NULL, NULL); - g_return_val_if_fail(name != NULL, NULL); - g_return_val_if_fail(value_type != NULL, NULL); - - attr = g_new0(PurpleStatusAttribute, 1); - - attr->id = g_strdup(id); - attr->name = g_strdup(name); - attr->value_type = value_type; - - return attr; -} - -void -purple_status_attribute_destroy(PurpleStatusAttribute *attr) -{ - g_return_if_fail(attr != NULL); - - g_free(attr->id); - g_free(attr->name); - - purple_value_free(attr->value_type); - - g_free(attr); -} - -const char * -purple_status_attribute_get_id(const PurpleStatusAttribute *attr) -{ - g_return_val_if_fail(attr != NULL, NULL); - - return attr->id; -} - -const char * -purple_status_attribute_get_name(const PurpleStatusAttribute *attr) -{ - g_return_val_if_fail(attr != NULL, NULL); - - return attr->name; -} - -GValue * -purple_status_attribute_get_value(const PurpleStatusAttribute *attr) -{ - g_return_val_if_fail(attr != NULL, NULL); - - return attr->value_type; -} - - -/************************************************************************** -* PurpleStatus API -**************************************************************************/ -static void -status_has_changed(PurpleStatus *status) -{ - PurplePresence *presence; - PurpleStatus *old_status; - - presence = purple_status_get_presence(status); - - /* - * If this status is exclusive, then we must be setting it to "active." - * Since we are setting it to active, we want to set the currently - * active status to "inactive." - */ - if (purple_status_is_exclusive(status)) - { - old_status = purple_presence_get_active_status(presence); - if (old_status != NULL && (old_status != status)) { - old_status->active = FALSE; - g_object_notify_by_pspec(G_OBJECT(old_status), - properties[PROP_ACTIVE]); - } - } - else - old_status = NULL; - - g_object_set(presence, "active-status", status, NULL); - g_object_notify_by_pspec(G_OBJECT(status), properties[PROP_ACTIVE]); -} - -static void -status_set_attr_boolean(PurpleStatus *status, const char *id, - gboolean value) -{ - GValue *attr_value; - - g_return_if_fail(PURPLE_IS_STATUS(status)); - g_return_if_fail(id != NULL); - - /* Make sure this attribute exists and is the correct type. */ - attr_value = purple_status_get_attr_value(status, id); - g_return_if_fail(attr_value != NULL); - g_return_if_fail(G_VALUE_TYPE(attr_value) == G_TYPE_BOOLEAN); - - g_value_set_boolean(attr_value, value); -} - -static void -status_set_attr_int(PurpleStatus *status, const char *id, int value) -{ - GValue *attr_value; - - g_return_if_fail(PURPLE_IS_STATUS(status)); - g_return_if_fail(id != NULL); - - /* Make sure this attribute exists and is the correct type. */ - attr_value = purple_status_get_attr_value(status, id); - g_return_if_fail(attr_value != NULL); - g_return_if_fail(G_VALUE_TYPE(attr_value) == G_TYPE_INT); - - g_value_set_int(attr_value, value); -} - -static void -status_set_attr_string(PurpleStatus *status, const char *id, - const char *value) -{ - GValue *attr_value; - - g_return_if_fail(PURPLE_IS_STATUS(status)); - g_return_if_fail(id != NULL); - - /* Make sure this attribute exists and is the correct type. */ - attr_value = purple_status_get_attr_value(status, id); - /* This used to be g_return_if_fail, but it's failing a LOT, so - * let's generate a log error for now. */ - /* g_return_if_fail(attr_value != NULL); */ - if (attr_value == NULL) { - purple_debug_error("status", - "Attempted to set status attribute '%s' for " - "status '%s', which is not legal. Fix " - "this!\n", id, - purple_status_type_get_name(purple_status_get_status_type(status))); - return; - } - g_return_if_fail(G_VALUE_TYPE(attr_value) == G_TYPE_STRING); - - /* XXX: Check if the value has actually changed. If it has, and the status - * is active, should this trigger 'status_has_changed'? */ - g_value_set_string(attr_value, value); -} - -void -purple_status_set_active(PurpleStatus *status, gboolean active) -{ - purple_status_set_active_with_attributes(status, active, NULL); -} - -void -purple_status_set_active_with_attributes(PurpleStatus *status, gboolean active, - GHashTable *attrs) -{ - gboolean changed = FALSE; - GList *l; - GList *specified_attr_ids = NULL; - PurpleStatusType *status_type; - - g_return_if_fail(PURPLE_IS_STATUS(status)); - - if(!active && purple_status_is_exclusive(status)) { - purple_debug_error("status", - "Cannot deactivate an exclusive status (%s).", - purple_status_get_id(status)); - return; - } - - if(status->active != active) { - changed = TRUE; - } - status->active = active; - - if(attrs != NULL) { - GHashTableIter iter; - gpointer key, data; - - /* Set any attributes */ - g_hash_table_iter_init(&iter, attrs); - while(g_hash_table_iter_next(&iter, &key, &data)) { - gchar *id = (gchar *)key; - GValue *value = purple_status_get_attr_value(status, id); - if(value == NULL) { - purple_debug_warning("status", - "The attribute \"%s\" on the status " - "\"%s\" is not supported.", - id, status->status_type->name); - - /* Skip over the data and move on to the next attribute */ - continue; - } - - specified_attr_ids = g_list_prepend(specified_attr_ids, id); - - if(G_VALUE_HOLDS_STRING(value)) { - const gchar *string_data = (const gchar *)data; - - if(purple_strequal(string_data, g_value_get_string(value))) { - continue; - } - - status_set_attr_string(status, id, string_data); - changed = TRUE; - } else if(G_VALUE_HOLDS_INT(value)) { - gint int_data = GPOINTER_TO_INT(data); - - if(int_data == g_value_get_int(value)) { - continue; - } - - status_set_attr_int(status, id, int_data); - changed = TRUE; - } else if(G_VALUE_HOLDS_BOOLEAN(value)) { - gboolean boolean_data = GPOINTER_TO_INT(data); - - if(boolean_data == g_value_get_boolean(value)) { - continue; - } - - status_set_attr_boolean(status, id, boolean_data); - changed = TRUE; - } - } - } - - /* Reset any unspecified attributes to their default value */ - status_type = purple_status_get_status_type(status); - l = purple_status_type_get_attrs(status_type); - while(l != NULL) { - PurpleStatusAttribute *attr; - GList *found = NULL; - GValue *default_value = NULL; - default_value = NULL; - - attr = l->data; - l = l->next; - - found = g_list_find_custom(specified_attr_ids, attr->id, - (GCompareFunc)g_strcmp0); - if(found != NULL) { - continue; - } - - default_value = purple_status_attribute_get_value(attr); - if(G_VALUE_HOLDS_STRING(default_value)) { - const gchar *cur = purple_status_get_attr_string(status, - attr->id); - const gchar *def = g_value_get_string(default_value); - - if (purple_strequal(cur, def)) { - continue; - } - - status_set_attr_string(status, attr->id, def); - } else if(G_VALUE_HOLDS_INT(default_value)) { - gint cur = purple_status_get_attr_int(status, attr->id); - gint def = g_value_get_int(default_value); - - if(cur == def) { - continue; - } - - status_set_attr_int(status, attr->id, def); - } else if(G_VALUE_HOLDS_BOOLEAN(default_value)) { - gboolean cur = purple_status_get_attr_boolean(status, attr->id); - gboolean def = g_value_get_boolean(default_value); - - if(cur == def) { - continue; - } - - status_set_attr_boolean(status, attr->id, def); - } - changed = TRUE; - } - g_list_free(specified_attr_ids); - - if(changed) { - status_has_changed(status); - } -} - -PurpleStatusType * -purple_status_get_status_type(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), NULL); - - return status->status_type; -} - -PurplePresence * -purple_status_get_presence(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), NULL); - - return status->presence; -} - -const char * -purple_status_get_id(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), NULL); - - return purple_status_type_get_id(purple_status_get_status_type(status)); -} - -const char * -purple_status_get_name(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), NULL); - - return purple_status_type_get_name(purple_status_get_status_type(status)); -} - -gboolean -purple_status_is_independent(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), FALSE); - - return purple_status_type_is_independent(purple_status_get_status_type(status)); -} - -gboolean -purple_status_is_exclusive(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), FALSE); - - return purple_status_type_is_exclusive(purple_status_get_status_type(status)); -} - -gboolean -purple_status_is_available(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), FALSE); - - return purple_status_type_is_available(purple_status_get_status_type(status)); -} - -gboolean -purple_status_is_active(PurpleStatus *status) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), FALSE); - - return status->active; -} - -gboolean -purple_status_is_online(PurpleStatus *status) -{ - PurpleStatusPrimitive primitive; - - g_return_val_if_fail(PURPLE_IS_STATUS(status), FALSE); - - primitive = purple_status_type_get_primitive(purple_status_get_status_type(status)); - - return (primitive != PURPLE_STATUS_UNSET && - primitive != PURPLE_STATUS_OFFLINE); -} - -GValue * -purple_status_get_attr_value(PurpleStatus *status, const char *id) -{ - g_return_val_if_fail(PURPLE_IS_STATUS(status), NULL); - g_return_val_if_fail(id != NULL, NULL); - - return (GValue *)g_hash_table_lookup(status->attr_values, id); -} - -gboolean -purple_status_get_attr_boolean(PurpleStatus *status, const char *id) -{ - const GValue *value; - - g_return_val_if_fail(PURPLE_IS_STATUS(status), FALSE); - g_return_val_if_fail(id != NULL, FALSE); - - if ((value = purple_status_get_attr_value(status, id)) == NULL) - return FALSE; - - g_return_val_if_fail(G_VALUE_TYPE(value) == G_TYPE_BOOLEAN, FALSE); - - return g_value_get_boolean(value); -} - -int -purple_status_get_attr_int(PurpleStatus *status, const char *id) -{ - const GValue *value; - - g_return_val_if_fail(PURPLE_IS_STATUS(status), 0); - g_return_val_if_fail(id != NULL, 0); - - if ((value = purple_status_get_attr_value(status, id)) == NULL) - return 0; - - g_return_val_if_fail(G_VALUE_TYPE(value) == G_TYPE_INT, 0); - - return g_value_get_int(value); -} - -const char * -purple_status_get_attr_string(PurpleStatus *status, const char *id) -{ - const GValue *value; - - g_return_val_if_fail(PURPLE_IS_STATUS(status), NULL); - g_return_val_if_fail(id != NULL, NULL); - - if ((value = purple_status_get_attr_value(status, id)) == NULL) - return NULL; - - g_return_val_if_fail(G_VALUE_TYPE(value) == G_TYPE_STRING, NULL); - - return g_value_get_string(value); -} - -gint -purple_status_compare(PurpleStatus *status1, PurpleStatus *status2) -{ - PurpleStatusType *type1, *type2; - int score1 = 0, score2 = 0; - - if ((status1 == NULL && status2 == NULL) || - (status1 == status2)) - { - return 0; - } - else if (status1 == NULL) - return 1; - else if (status2 == NULL) - return -1; - - type1 = purple_status_get_status_type(status1); - type2 = purple_status_get_status_type(status2); - - if (purple_status_is_active(status1)) - score1 = primitive_scores[purple_status_type_get_primitive(type1)]; - - if (purple_status_is_active(status2)) - score2 = primitive_scores[purple_status_type_get_primitive(type2)]; - - if (score1 > score2) - return -1; - else if (score1 < score2) - return 1; - - return 0; -} - - -/************************************************************************** -* GBoxed code for PurpleStatusType -**************************************************************************/ -static PurpleStatusType * -purple_status_type_ref(PurpleStatusType *status_type) -{ - g_return_val_if_fail(status_type != NULL, NULL); - - status_type->box_count++; - - return status_type; -} - -static void -purple_status_type_unref(PurpleStatusType *status_type) -{ - g_return_if_fail(status_type != NULL); - g_return_if_fail(status_type->box_count >= 0); - - if (!status_type->box_count--) - purple_status_type_destroy(status_type); -} - -GType -purple_status_type_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - type = g_boxed_type_register_static("PurpleStatusType", - (GBoxedCopyFunc)purple_status_type_ref, - (GBoxedFreeFunc)purple_status_type_unref); - } - - return type; -} - -/************************************************************************** -* GBoxed code for PurpleStatusAttribute -**************************************************************************/ -static PurpleStatusAttribute * -purple_status_attribute_copy(PurpleStatusAttribute *status_attr) -{ - g_return_val_if_fail(status_attr != NULL, NULL); - - return purple_status_attribute_new(status_attr->id, - status_attr->name, - purple_value_dup(status_attr->value_type)); -} - -GType -purple_status_attribute_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - type = g_boxed_type_register_static("PurpleStatusAttribute", - (GBoxedCopyFunc)purple_status_attribute_copy, - (GBoxedFreeFunc)purple_status_attribute_destroy); - } - - return type; -} - -/************************************************************************** -* GObject code -**************************************************************************/ - -/* Set method for GObject properties */ -static void -purple_status_set_property(GObject *obj, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleStatus *status = PURPLE_STATUS(obj); - - switch (param_id) { - case PROP_STATUS_TYPE: - status->status_type = g_value_get_pointer(value); - break; - case PROP_PRESENCE: - status->presence = g_value_get_object(value); - break; - case PROP_ACTIVE: - purple_status_set_active(status, g_value_get_boolean(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* Get method for GObject properties */ -static void -purple_status_get_property(GObject *obj, guint param_id, GValue *value, - GParamSpec *pspec) -{ - PurpleStatus *status = PURPLE_STATUS(obj); - - switch (param_id) { - case PROP_STATUS_TYPE: - g_value_set_pointer(value, purple_status_get_status_type(status)); - break; - case PROP_PRESENCE: - g_value_set_object(value, purple_status_get_presence(status)); - break; - case PROP_ACTIVE: - g_value_set_boolean(value, purple_status_is_active(status)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* GObject initialization function */ -static void -purple_status_init(PurpleStatus *status) -{ - status->attr_values = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, - (GDestroyNotify)purple_value_free); -} - -/* Called when done constructing */ -static void -purple_status_constructed(GObject *object) -{ - PurpleStatus *status = PURPLE_STATUS(object); - GList *l; - - G_OBJECT_CLASS(purple_status_parent_class)->constructed(object); - - for (l = purple_status_type_get_attrs(status->status_type); l != NULL; l = l->next) - { - PurpleStatusAttribute *attr = (PurpleStatusAttribute *)l->data; - GValue *value = purple_status_attribute_get_value(attr); - GValue *new_value = purple_value_dup(value); - - g_hash_table_insert(status->attr_values, - (char *)purple_status_attribute_get_id(attr), - new_value); - } -} - -/* - * GObject finalize function - * TODO: If the PurpleStatus is in a PurplePresence, then - * remove it from the PurplePresence? - */ -static void -purple_status_finalize(GObject *obj) -{ - PurpleStatus *status = PURPLE_STATUS(obj); - - g_hash_table_destroy(status->attr_values); - - G_OBJECT_CLASS(purple_status_parent_class)->finalize(obj); -} - -/* Class initializer function */ -static void -purple_status_class_init(PurpleStatusClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - obj_class->finalize = purple_status_finalize; - obj_class->constructed = purple_status_constructed; - - /* Setup properties */ - obj_class->get_property = purple_status_get_property; - obj_class->set_property = purple_status_set_property; - - /** - * PurpleStatus:status-type: - * - * The type of this status. - * - * Since: 3.0 - */ - properties[PROP_STATUS_TYPE] = g_param_spec_pointer("status-type", - "Status type", - "The PurpleStatusType of the status.", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - /** - * PurpleStatus:presence: - * - * The presence that the status belongs to. - * - * Since: 3.0 - */ - properties[PROP_PRESENCE] = g_param_spec_object("presence", "Presence", - "The presence that the status belongs to.", - PURPLE_TYPE_PRESENCE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - - /** - * PurpleStatus:active: - * - * Whether or not the status is active. - * - * Since: 3.0 - */ - properties[PROP_ACTIVE] = g_param_spec_boolean("active", "Active", - "Whether the status is active or not.", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(obj_class, N_PROPERTIES, properties); -} - -PurpleStatus * -purple_status_new(PurpleStatusType *status_type, PurplePresence *presence) -{ - g_return_val_if_fail(status_type != NULL, NULL); - g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL); - - return g_object_new(PURPLE_TYPE_STATUS, - "status-type", status_type, - "presence", presence, - NULL); -} - - -/************************************************************************** -* Status subsystem -**************************************************************************/ -static void -score_pref_changed_cb(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED PurplePrefType type, gconstpointer value, - gpointer data) -{ - int index = GPOINTER_TO_INT(data); - - primitive_scores[index] = GPOINTER_TO_INT(value); -} - -void * -purple_statuses_get_handle(void) { - static int handle; - - return &handle; -} - -void -purple_statuses_init(void) -{ - void *handle = purple_statuses_get_handle(); - - purple_prefs_add_none("/purple/status"); - purple_prefs_add_none("/purple/status/scores"); - - purple_prefs_add_int("/purple/status/scores/offline", - primitive_scores[PURPLE_STATUS_OFFLINE]); - purple_prefs_add_int("/purple/status/scores/available", - primitive_scores[PURPLE_STATUS_AVAILABLE]); - purple_prefs_add_int("/purple/status/scores/invisible", - primitive_scores[PURPLE_STATUS_INVISIBLE]); - purple_prefs_add_int("/purple/status/scores/away", - primitive_scores[PURPLE_STATUS_AWAY]); - purple_prefs_add_int("/purple/status/scores/extended_away", - primitive_scores[PURPLE_STATUS_EXTENDED_AWAY]); - purple_prefs_add_int("/purple/status/scores/idle", - primitive_scores[SCORE_IDLE]); - purple_prefs_add_int("/purple/status/scores/idle_time", - primitive_scores[SCORE_IDLE_TIME]); - purple_prefs_add_int("/purple/status/scores/offline_msg", - primitive_scores[SCORE_OFFLINE_MESSAGE]); - - purple_prefs_connect_callback(handle, "/purple/status/scores/offline", - score_pref_changed_cb, - GINT_TO_POINTER(PURPLE_STATUS_OFFLINE)); - purple_prefs_connect_callback(handle, "/purple/status/scores/available", - score_pref_changed_cb, - GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE)); - purple_prefs_connect_callback(handle, "/purple/status/scores/invisible", - score_pref_changed_cb, - GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE)); - purple_prefs_connect_callback(handle, "/purple/status/scores/away", - score_pref_changed_cb, - GINT_TO_POINTER(PURPLE_STATUS_AWAY)); - purple_prefs_connect_callback(handle, "/purple/status/scores/extended_away", - score_pref_changed_cb, - GINT_TO_POINTER(PURPLE_STATUS_EXTENDED_AWAY)); - purple_prefs_connect_callback(handle, "/purple/status/scores/idle", - score_pref_changed_cb, - GINT_TO_POINTER(SCORE_IDLE)); - purple_prefs_connect_callback(handle, "/purple/status/scores/idle_time", - score_pref_changed_cb, - GINT_TO_POINTER(SCORE_IDLE_TIME)); - purple_prefs_connect_callback(handle, "/purple/status/scores/offline_msg", - score_pref_changed_cb, - GINT_TO_POINTER(SCORE_OFFLINE_MESSAGE)); - - purple_prefs_trigger_callback("/purple/status/scores/offline"); - purple_prefs_trigger_callback("/purple/status/scores/available"); - purple_prefs_trigger_callback("/purple/status/scores/invisible"); - purple_prefs_trigger_callback("/purple/status/scores/away"); - purple_prefs_trigger_callback("/purple/status/scores/extended_away"); - purple_prefs_trigger_callback("/purple/status/scores/idle"); - purple_prefs_trigger_callback("/purple/status/scores/idle_time"); - purple_prefs_trigger_callback("/purple/status/scores/offline_msg"); -} - -void -purple_statuses_uninit(void) -{ - purple_prefs_disconnect_by_handle(purple_statuses_get_handle()); -} - -/**************************************************************************/ -/* Helpers */ -/**************************************************************************/ -GHashTable * -purple_attrs_from_vargs(va_list args) -{ - GHashTable *attrs = g_hash_table_new(g_str_hash, g_str_equal); - gchar *id; - - while ((id = va_arg(args, gchar *)) != NULL) - { - gpointer data = va_arg(args, gpointer); - - g_hash_table_insert(attrs, id, data); - } - - return attrs; -}
--- a/libpurple/status.h Fri Apr 12 01:55:22 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,892 +0,0 @@ -/* - * Purple - Internet Messaging Library - * 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 library 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 library 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 library; 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_STATUS_H -#define PURPLE_STATUS_H - -#include "purpleversion.h" - -#define PURPLE_TYPE_STATUS (purple_status_get_type()) -typedef struct _PurpleStatus PurpleStatus; - -#define PURPLE_TYPE_STATUS_TYPE (purple_status_type_get_type()) - -/** - * PurpleStatusType: - * - * PurpleStatusType's are created by each protocol. They outline the - * available statuses of the protocol. AIM, for example, supports - * an available state with an optional available message, an away - * state with a mandatory message, and an invisible state (which is - * technically "independent" of the other two, but we'll get into - * that later). PurpleStatusTypes are very permanent. They are - * hardcoded in each protocol and will not change often. And because - * they are hardcoded, they do not need to be saved to any XML file. - * - * Since: 2.0 - */ -typedef struct _PurpleStatusType PurpleStatusType; - -#define PURPLE_TYPE_STATUS_ATTRIBUTE (purple_status_attribute_get_type()) - -/** - * PurpleStatus: - * - * A PurpleStatus can be thought of as an "instance" of a PurpleStatusType. - * If you're familiar with object-oriented programming languages - * then this should be immediately clear. Say, for example, that - * one of your AIM buddies has set himself as "away." You have a - * PurpleBuddy node for this person in your buddy list. Purple wants - * to mark this buddy as "away," so it creates a new PurpleStatus. - * The PurpleStatus has its PurpleStatusType set to the "away" state - * for the oscar protocol. The PurpleStatus also contains the buddy's - * away message. PurpleStatuses are sometimes saved, depending on - * the context. The current PurpleStatuses associated with each of - * your accounts are saved so that the next time you start Purple, - * your accounts will be set to their last known statuses. There - * is also a list of saved statuses that are written to the - * status.xml file. Also, each PurpleStatus has a "saveable" boolean. - * If "saveable" is set to FALSE then the status is NEVER saved. - * All PurpleStatuses should be inside a PurplePresence. - * - * A PurpleStatus is either "independent" or "exclusive." - * Independent statuses can be active or inactive and they don't - * affect anything else. However, you can only have one exclusive - * status per PurplePresence. If you activate one exclusive status, - * then the previous exclusive status is automatically deactivated. - * - * A PurplePresence is like a collection of PurpleStatuses (plus some - * other random info). - * - * See <link linkend="libpurple-purplepresence">Presence API</link> - * - * Since: 2.0 - */ - -/** - * PurpleStatusAttribute: - * - * An attribute that can be added to a status. - * - * Since: 2.0 - */ -typedef struct _PurpleStatusAttribute PurpleStatusAttribute; - -/** - * PurpleStatusPrimitive: - * @PURPLE_STATUS_UNSET: The status is not set - * @PURPLE_STATUS_OFFLINE: The status is offline - * @PURPLE_STATUS_AVAILABLE: The status is available - * @PURPLE_STATUS_UNAVAILABLE: The status is unavailable - * @PURPLE_STATUS_INVISIBLE: The stuatus is invisible - * @PURPLE_STATUS_AWAY: The status is away - * @PURPLE_STATUS_EXTENDED_AWAY: The status is extended away/do not disturb - * @PURPLE_STATUS_MOBILE: The status is mobile - * @PURPLE_STATUS_NUM_PRIMITIVES: The number of #PurpleStatusPrimitive<!-- -->s - * - * A primitive defining the basic structure of a status type. - * - * Since: 2.0 - */ -/* - * If you add a value to this enum, make sure you update - * the status_primitive_map and primitive_scores arrays in status.c. - */ -typedef enum -{ - PURPLE_STATUS_UNSET = 0, - PURPLE_STATUS_OFFLINE, - PURPLE_STATUS_AVAILABLE, - PURPLE_STATUS_UNAVAILABLE, - PURPLE_STATUS_INVISIBLE, - PURPLE_STATUS_AWAY, - PURPLE_STATUS_EXTENDED_AWAY, - PURPLE_STATUS_MOBILE, - - PURPLE_STATUS_NUM_PRIMITIVES, /*< skip >*/ -} PurpleStatusPrimitive; - -#include "purplepresence.h" - -G_BEGIN_DECLS - -/**************************************************************************/ -/* PurpleStatusPrimitive API */ -/**************************************************************************/ - -/** - * purple_primitive_get_id_from_type: - * @type: A primitive status type. - * - * Lookup the id of a primitive status type based on the type. This - * ID is a unique plain-text name of the status, without spaces. - * - * Returns: The unique ID for this type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_primitive_get_id_from_type(PurpleStatusPrimitive type); - -/** - * purple_primitive_get_name_from_type: - * @type: A primitive status type. - * - * Lookup the name of a primitive status type based on the type. This - * name is the plain-English name of the status type. It is usually one - * or two words. - * - * Returns: The name of this type, suitable for users to see. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_primitive_get_name_from_type(PurpleStatusPrimitive type); - -/** - * purple_primitive_get_type_from_id: - * @id: The unique ID of a primitive status type. - * - * Lookup the value of a primitive status type based on the id. The - * ID is a unique plain-text name of the status, without spaces. - * - * Returns: The PurpleStatusPrimitive value. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusPrimitive purple_primitive_get_type_from_id(const char *id); - -/**************************************************************************/ -/* PurpleStatusType API */ -/**************************************************************************/ - -/** - * purple_status_type_get_type: - * - * The standard _get_type function for #PurpleStatusType. - * - * Returns: The #GType for #PurpleStatusType. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GType purple_status_type_get_type(void); - -/** - * purple_status_type_new_full: - * @primitive: The primitive status type. - * @id: The ID of the status type, or %NULL to use the id of the primitive - * status type. - * @name: The name presented to the user, or %NULL to use the name of the - * primitive status type. - * @saveable: %TRUE if the information set for this status by the user can be - * saved for future sessions. - * @user_settable: %TRUE if this is a status the user can manually set. - * @independent: %TRUE if this is an independent (non-exclusive) status type. - * - * Creates a new status type. - * - * Returns: (transfer full): A new status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusType *purple_status_type_new_full(PurpleStatusPrimitive primitive, - const char *id, const char *name, - gboolean saveable, - gboolean user_settable, - gboolean independent); - -/** - * purple_status_type_new: - * @primitive: The primitive status type. - * @id: The ID of the status type, or %NULL to use the id of the primitive - * status type. - * @name: The name presented to the user, or %NULL to use the name of the - * primitive status type. - * @user_settable: %TRUE if this is a status the user can manually set. - * - * Creates a new status type with some default values (saveable and not - * independent). - * - * Returns: (transfer full): A new status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusType *purple_status_type_new(PurpleStatusPrimitive primitive, - const char *id, const char *name, - gboolean user_settable); - -/** - * purple_status_type_new_with_attrs: - * @primitive: The primitive status type. - * @id: The ID of the status type, or %NULL to use the id of the primitive - * status type. - * @name: The name presented to the user, or %NULL to use the name of the - * primitive status type. - * @saveable: %TRUE if the information set for this status by the user can be - * saved for future sessions. - * @user_settable: %TRUE if this is a status the user can manually set. - * @independent: %TRUE if this is an independent (non-exclusive) status type. - * @attr_id: The ID of the first attribute. - * @attr_name: The name of the first attribute. - * @attr_value: The value type of the first attribute. - * @...: Additional attribute information. - * - * Creates a new status type with attributes. - * - * Returns: (transfer full): A new status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusType *purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive, - const char *id, - const char *name, - gboolean saveable, - gboolean user_settable, - gboolean independent, - const char *attr_id, - const char *attr_name, - GValue *attr_value, ...) G_GNUC_NULL_TERMINATED; - -/** - * purple_status_type_new_with_attrsv: (rename-to purple_status_type_new_with_attrs): - * @primitive: The primitive status type. - * @id: The ID of the status type, or %NULL to use the id of the primitive - * status type. - * @name: The name presented to the user, or %NULL to use the name of the - * primitive status type. - * @saveable: %TRUE if the information set for this status by the user can be - * saved for future sessions. - * @user_settable: %TRUE if this is a status the user can manually set. - * @independent: %TRUE if this is an independent (non-exclusive) status type. - * @n_attributes: The number of attributes. - * @attr_id: (array length=n_attributes): The IDs of the attributes. - * @attr_name: (array length=n_attributes): The names of the attributes. - * @attr_value: (array length=n_attributes): The value types of the attributes. - * - * Creates a new status type with attributes. - * - * Returns: (transfer full): A new status type. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleStatusType *purple_status_type_new_with_attrsv(PurpleStatusPrimitive primitive, - const gchar *id, - const gchar *name, - gboolean saveable, - gboolean user_settable, - gboolean independent, - guint n_attributes, - const gchar *attr_id[], - const gchar *attr_name[], - GValue *attr_value[]); - -/** - * purple_status_type_destroy: - * @status_type: The status type to destroy. - * - * Destroys a status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_status_type_destroy(PurpleStatusType *status_type); - -/** - * purple_status_type_get_primitive: - * @status_type: The status type. - * - * Returns the primitive type of a status type. - * - * Returns: The primitive type of the status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusPrimitive purple_status_type_get_primitive( - const PurpleStatusType *status_type); - -/** - * purple_status_type_get_id: - * @status_type: The status type. - * - * Returns the ID of a status type. - * - * Returns: The ID of the status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_status_type_get_id(const PurpleStatusType *status_type); - -/** - * purple_status_type_get_name: - * @status_type: The status type. - * - * Returns the name of a status type. - * - * Returns: The name of the status type. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_status_type_get_name(const PurpleStatusType *status_type); - -/** - * purple_status_type_is_saveable: - * @status_type: The status type. - * - * Returns whether or not the status type is saveable. - * - * Returns: TRUE if user-defined statuses based off this type are saveable. - * FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_type_is_saveable(const PurpleStatusType *status_type); - -/** - * purple_status_type_is_user_settable: - * @status_type: The status type. - * - * Returns whether or not the status type can be set or modified by the - * user. - * - * Returns: TRUE if the status type can be set or modified by the user. - * FALSE if it's a protocol-set setting. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_type_is_user_settable(const PurpleStatusType *status_type); - -/** - * purple_status_type_is_independent: - * @status_type: The status type. - * - * Returns whether or not the status type is independent. - * - * Independent status types are non-exclusive. If other status types on - * the same hierarchy level are set, this one will not be affected. - * - * Returns: TRUE if the status type is independent, or FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_type_is_independent(const PurpleStatusType *status_type); - -/** - * purple_status_type_is_exclusive: - * @status_type: The status type. - * - * Returns whether the status type is exclusive. - * - * Returns: TRUE if the status type is exclusive, FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_type_is_exclusive(const PurpleStatusType *status_type); - -/** - * purple_status_type_is_available: - * @status_type: The status type. - * - * Returns whether or not a status type is available. - * - * Available status types are online and possibly invisible, but not away. - * - * Returns: TRUE if the status is available, or FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_type_is_available(const PurpleStatusType *status_type); - -/** - * purple_status_type_get_attr: - * @status_type: The status type containing the attribute. - * @id: The ID of the desired attribute. - * - * Returns the attribute with the specified ID. - * - * Returns: The attribute, if found. NULL otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatusAttribute *purple_status_type_get_attr(const PurpleStatusType *status_type, - const char *id); - -/** - * purple_status_type_get_attrs: - * @status_type: The status type. - * - * Returns a list of all attributes in a status type. - * - * Returns: (element-type PurpleStatusAttribute) (transfer none): The list of attributes. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GList *purple_status_type_get_attrs(const PurpleStatusType *status_type); - -/** - * purple_status_type_find_with_id: - * @status_types: (element-type PurpleStatus) (transfer none): A list of status - * types. Often account->status_types. - * @id: The unique ID of the status type you wish to find. - * - * Find the PurpleStatusType with the given id. - * - * Returns: The status type with the given ID, or NULL if one could - * not be found. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const PurpleStatusType *purple_status_type_find_with_id(GList *status_types, - const char *id); - -/**************************************************************************/ -/* PurpleStatusAttribute API */ -/**************************************************************************/ - -/** - * purple_status_attribute_get_type: - * - * The standard _get_type function for #PurpleStatusAttribute. - * - * Returns: The #GType for the #PurpleStatusAttribute boxed structure. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GType purple_status_attribute_get_type(void); - -/** - * purple_status_attribute_new: - * @id: The ID of the attribute. - * @name: The name presented to the user. - * @value_type: The type of data contained in the attribute. - * - * Creates a new status attribute. - * - * Returns: A new status attribute. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleStatusAttribute *purple_status_attribute_new(const char *id, const char *name, - GValue *value_type); - -/** - * purple_status_attribute_destroy: - * @attr: The status attribute to destroy. - * - * Destroys a status attribute. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_status_attribute_destroy(PurpleStatusAttribute *attr); - -/** - * purple_status_attribute_get_id: - * @attr: The status attribute. - * - * Returns the ID of a status attribute. - * - * Returns: The status attribute's ID. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_status_attribute_get_id(const PurpleStatusAttribute *attr); - -/** - * purple_status_attribute_get_name: - * @attr: The status attribute. - * - * Returns the name of a status attribute. - * - * Returns: The status attribute's name. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_status_attribute_get_name(const PurpleStatusAttribute *attr); - -/** - * purple_status_attribute_get_value: - * @attr: The status attribute. - * - * Returns the value of a status attribute. - * - * Returns: The status attribute's value. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GValue *purple_status_attribute_get_value(const PurpleStatusAttribute *attr); - -/**************************************************************************/ -/* PurpleStatus API */ -/**************************************************************************/ - -/** - * purple_status_get_type: - * - * The standard _get_type function for #PurpleStatus. - * - * Returns: The #GType for #PurpleStatus. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -G_DECLARE_FINAL_TYPE(PurpleStatus, purple_status, PURPLE, STATUS, GObject) - -/** - * purple_status_new: - * @status_type: The type of status. - * @presence: The parent presence. - * - * Creates a new status. - * - * Returns: The new status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleStatus *purple_status_new(PurpleStatusType *status_type, - PurplePresence *presence); - -/** - * purple_status_set_active: - * @status: The status. - * @active: The active state. - * - * Sets whether or not a status is active. - * - * This should only be called by the account, conversation, and buddy APIs. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_status_set_active(PurpleStatus *status, gboolean active); - -/** - * purple_status_set_active_with_attributes: - * @status: The status. - * @active: The active state. - * @attrs: (nullable) (element-type utf8 gpointer): A hash table of attributes - * to set on the status. This hash table's keys are valid attribute - * names for this PurpleStatusType. The hash table is not modified or - * freed by this function. - * - * Sets whether or not a status is active. - * - * This should only be called by the account, conversation, and buddy APIs. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_status_set_active_with_attributes(PurpleStatus *status, gboolean active, GHashTable *attrs); - -/** - * purple_status_get_status_type: - * @status: The status. - * - * Returns the status's type. - * - * Returns: The status's type. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleStatusType *purple_status_get_status_type(PurpleStatus *status); - -/** - * purple_status_get_presence: - * @status: The status. - * - * Returns the status's presence. - * - * Returns: (transfer none): The status's presence. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurplePresence *purple_status_get_presence(PurpleStatus *status); - -/** - * purple_status_get_id: - * @status: The status. - * - * Returns the status's type ID. - * - * This is a convenience method for - * purple_status_type_get_id(purple_status_get_status_type(status)). - * - * Returns: The status's ID. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_status_get_id(PurpleStatus *status); - -/** - * purple_status_get_name: - * @status: The status. - * - * Returns the status's name. - * - * This is a convenience method for - * purple_status_type_get_name(purple_status_get_status_type(status)). - * - * Returns: The status's name. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_status_get_name(PurpleStatus *status); - -/** - * purple_status_is_independent: - * @status: The status. - * - * Returns whether or not a status is independent. - * - * This is a convenience method for - * purple_status_type_is_independent(purple_status_get_status_type(status)). - * - * Returns: TRUE if the status is independent, or FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_is_independent(PurpleStatus *status); - -/** - * purple_status_is_exclusive: - * @status: The status. - * - * Returns whether or not a status is exclusive. - * - * This is a convenience method for - * purple_status_type_is_exclusive(purple_status_get_status_type(status)). - * - * Returns: TRUE if the status is exclusive, FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_is_exclusive(PurpleStatus *status); - -/** - * purple_status_is_available: - * @status: The status. - * - * Returns whether or not a status is available. - * - * Available statuses are online and possibly invisible, but not away or idle. - * - * This is a convenience method for - * purple_status_type_is_available(purple_status_get_status_type(status)). - * - * Returns: TRUE if the status is available, or FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_is_available(PurpleStatus *status); - -/** - * purple_status_is_active: - * @status: The status. - * - * Returns the active state of a status. - * - * Returns: The active state of the status. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_is_active(PurpleStatus *status); - -/** - * purple_status_is_online: - * @status: The status. - * - * Returns whether or not a status is considered 'online' - * - * Returns: TRUE if the status is considered online, FALSE otherwise - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_is_online(PurpleStatus *status); - -/** - * purple_status_get_attr_value: - * @status: The status. - * @id: The attribute ID. - * - * Returns the value of an attribute in a status with the specified ID. - * - * Returns: The value of the attribute. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GValue *purple_status_get_attr_value(PurpleStatus *status, - const char *id); - -/** - * purple_status_get_attr_boolean: - * @status: The status. - * @id: The attribute ID. - * - * Returns the boolean value of an attribute in a status with the specified ID. - * - * Returns: The boolean value of the attribute. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_status_get_attr_boolean(PurpleStatus *status, - const char *id); - -/** - * purple_status_get_attr_int: - * @status: The status. - * @id: The attribute ID. - * - * Returns the integer value of an attribute in a status with the specified ID. - * - * Returns: The integer value of the attribute. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -int purple_status_get_attr_int(PurpleStatus *status, const char *id); - -/** - * purple_status_get_attr_string: - * @status: The status. - * @id: The attribute ID. - * - * Returns the string value of an attribute in a status with the specified ID. - * - * Returns: The string value of the attribute. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_status_get_attr_string(PurpleStatus *status, const char *id); - -/** - * purple_status_compare: - * @status1: The first status. - * @status2: The second status. - * - * Compares two statuses for availability. - * - * Returns: -1 if @status1 is more available than @status2. - * 0 if @status1 is equal to @status2. - * 1 if @status2 is more available than @status1. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gint purple_status_compare(PurpleStatus *status1, PurpleStatus *status2); - -/**************************************************************************/ -/* Statuses subsystem */ -/**************************************************************************/ - -/** - * purple_statuses_get_handle: - * - * Get the handle for the status subsystem. - * - * Returns: the handle to the status subsystem - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void *purple_statuses_get_handle(void); - -/** - * purple_statuses_init: - * - * Initializes the status subsystem. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_statuses_init(void); - -/** - * purple_statuses_uninit: - * - * Uninitializes the status subsystem. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_statuses_uninit(void); - -/**************************************************************************/ -/* Helpers */ -/**************************************************************************/ - -/** - * purple_attrs_from_vargs: - * @args: A list of attributes to parse. This list is - * composed of key/value pairs, where each key is a valid - * attribute name for this PurpleStatusType. The list should - * be NULL terminated. - * - * Returns a hash table of attributes constructed from args. - * - * Returns: (element-type utf8 gpointer) (transfer container): The hash table of attributes. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GHashTable *purple_attrs_from_vargs(va_list args); - -G_END_DECLS - -#endif /* PURPLE_STATUS_H */
--- a/po/POTFILES.in Fri Apr 12 01:55:22 2024 -0500 +++ b/po/POTFILES.in Fri Apr 12 02:08:00 2024 -0500 @@ -97,10 +97,8 @@ libpurple/request/purplerequestgroup.c libpurple/request/purplerequestpage.c libpurple/roomlist.c -libpurple/savedstatuses.c libpurple/server.c libpurple/signals.c -libpurple/status.c libpurple/tests/test_account_manager.c libpurple/tests/test_account_option.c libpurple/tests/test_circular_buffer.c