diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2010-06-15 17:14:57 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2010-06-15 17:14:57 +0100 |
commit | 725fcb43c8b108d5431d705816def175da706d72 (patch) | |
tree | 853387b505762e01c2562bf9d158fd9b9f20c6ad | |
parent | b4b672525723f1555aab1a31f84ef19c52cf1bee (diff) |
-rw-r--r-- | src/mcd-account-nickname.c | 218 | ||||
-rw-r--r-- | src/mcd-account.c | 23 | ||||
-rw-r--r-- | src/mcd-connection.c | 135 |
3 files changed, 241 insertions, 135 deletions
diff --git a/src/mcd-account-nickname.c b/src/mcd-account-nickname.c new file mode 100644 index 00000000..f694e626 --- /dev/null +++ b/src/mcd-account-nickname.c @@ -0,0 +1,218 @@ +/* Account - manipulation of the user's own nickname + * + * Copyright © 2008-2009 Nokia Corporation. + * Copyright © 2009-2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "config.h" +#include "mcd-account.h" +#include "mcd-account-priv.h" + +gboolean +_mcd_account_set_nickname (TpSvcDBusProperties *self, + const gchar *name, + const GValue *value, + GError **error) +{ + McdAccount *account = MCD_ACCOUNT (self); + McdAccountPrivate *priv = account->priv; + SetResult ret; + + DEBUG ("called for %s", priv->unique_name); + ret = mcd_account_set_string_val (account, name, value, error); + + if (ret == SET_RESULT_CHANGED && priv->connection != NULL) + { + /* this is a no-op if the connection doesn't support it */ + _mcd_connection_set_nickname (priv->connection, + g_value_get_string (value)); + } + + return (ret != SET_RESULT_ERROR); +} + +static void +get_nickname (TpSvcDBusProperties *self, const gchar *name, GValue *value) +{ + McdAccount *account = MCD_ACCOUNT (self); + + mcd_account_get_string_val (account, name, value); +} + +static void +mcd_account_connection_self_nickname_changed_cb (McdAccount *account, + const gchar *alias, + McdConnection *connection) +{ + GValue value = { 0 }; + + g_value_init (&value, G_TYPE_STRING); + g_value_set_static_string (&value, alias); + mcd_account_set_string_val (account, MC_ACCOUNTS_KEY_ALIAS, &value, NULL); + g_value_unset (&value); +} + +gchar * +mcd_account_get_alias (McdAccount *account) +{ + McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account); + + return g_key_file_get_string (priv->keyfile, priv->unique_name, + MC_ACCOUNTS_KEY_ALIAS, NULL); +} + +static void +on_aliases_changed (TpConnection *proxy, const GPtrArray *aliases, + gpointer user_data, GObject *weak_object) +{ + McdConnectionPrivate *priv = user_data; + guint self_handle; + guint i; + + DEBUG ("called"); + + self_handle = tp_connection_get_self_handle (proxy); + + for (i = 0; i < aliases->len; i++) + { + GValueArray *structure = g_ptr_array_index (aliases, i); + + if (g_value_get_uint (structure->values) == self_handle) + { + const gchar *alias = g_value_get_string (structure->values + 1); + + DEBUG ("Our alias on %s changed to %s", + tp_proxy_get_object_path (proxy), alias); + + if (priv->alias == NULL || tp_strdiff (priv->alias, alias)) + { + g_free (priv->alias); + priv->alias = g_strdup (alias); + g_signal_emit (weak_object, signals[SELF_NICKNAME_CHANGED], + 0, alias); + } + break; + } + } +} + +static void +mcd_account_nickname_set_aliases_cb (TpConnection *connection, + const GError *error, + gpointer user_data G_GNUC_UNUSED, + GObject *weak_object G_GNUC_UNUSED) +{ + if (error != NULL) + { + DEBUG ("SetAliases({SelfHandle: x}) failed: %s", error->message); + } +} + +void +_mcd_connection_set_nickname (McdConnection *connection, + const gchar *nickname) +{ + McdConnectionPrivate *priv = connection->priv; + + if (!priv->has_alias_if) + return; +} + +static void +mcd_account_nickname_get_aliases_cb (TpConnection *connection, + GHashTable *aliases, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + guint self_handle; + const gchar *alias; + + DEBUG ("called"); + + if (error != NULL) + { + DEBUG ("GetAliases([SelfHandle]) failed: %s", error->message); + return; + } + + self_handle = tp_connection_get_self_handle (connection); + + alias = g_hash_table_lookup (aliases, GUINT_TO_POINTER (self_handle)); + + /* FIXME: priv */ + + if (alias != NULL && + (priv->alias == NULL || tp_strdiff (priv->alias, alias))) + { + g_free (priv->alias); + priv->alias = g_strdup (alias); + + /* FIXME: inline SELF_NICKNAME_CHANGED */ + } +} + +void +_mcd_account_nickname_watch_connection (McdAccount *self, + TpConnection *connection) +{ + GArray *self_handle_array; + guint self_handle; + gchar *nickname; + + if (!tp_proxy_has_interface_by_id (connection, + TP_IFACE_QUARK_CONNECTION_INTERFACE_ALIASING)) + return; + + self_handle_array = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); + self_handle = tp_connection_get_self_handle (priv->tp_conn); + g_array_append_val (self_handle_array, self_handle); + + tp_cli_connection_interface_aliasing_connect_to_aliases_changed ( + connection, mcd_account_nickname_aliases_changed_cb, + NULL, NULL, (GObject *) self, NULL); + + tp_cli_connection_interface_aliasing_call_get_aliases + (connection, -1, self_handle_array, mcd_account_nickname_get_aliases_cb, + NULL, NULL, (GObject *) self); + + g_array_free (self_handle_array, TRUE); + + /* FIXME: ideally, on protocols with server-stored nicknames, this should + * only be done if the local Nickname has been changed since last time we + * were online; Aliasing doesn't currently offer a way to tell whether + * this is such a protocol, though. */ + + nickname = mcd_account_get_alias (self); + + if (nickname != NULL) + { + GHashTable *aliases; + + DEBUG ("setting nickname '%s' using Aliasing", nickname); + + aliases = g_hash_table_new (NULL, NULL); + g_hash_table_insert (aliases, GUINT_TO_POINTER (self_handle), nickname); + tp_cli_connection_interface_aliasing_call_set_aliases (connection, -1, + aliases, mcd_account_nickname_set_aliases_cb, NULL, NULL, + (GObject *) self); + g_hash_table_destroy (aliases); + } + + g_free (nickname); +} diff --git a/src/mcd-account.c b/src/mcd-account.c index 37347c6f..3a33982c 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -3366,6 +3366,23 @@ on_conn_status_changed (McdConnection *connection, _mcd_account_set_connection_status (account, status, reason, tp_conn); } +static void +mcd_account_tp_conn_connected_cb (GObject *tp_conn, + GAsyncResult *result, + gpointer user_data) +{ + McdAccount *self = tp_weak_ref_dup_object (user_data); + + if (self == NULL) + goto finally; + + _mcd_account_nickname_watch_connection (self, tp_conn); + +finally: + tp_clear_object (&self); + tp_weak_ref_destroy (user_data); +} + void _mcd_account_set_connection_status (McdAccount *account, TpConnectionStatus status, @@ -3396,8 +3413,14 @@ _mcd_account_set_connection_status (McdAccount *account, if (tp_conn != NULL) { + GQuark features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 }; + priv->tp_connection = g_object_ref (tp_conn); path = tp_proxy_get_object_path (tp_conn); + + tp_proxy_prepare_async (tp_conn, conn_features, + mcd_account_tp_conn_connected_cb, + tp_weak_ref_new (self, NULL, NULL)); } else { diff --git a/src/mcd-connection.c b/src/mcd-connection.c index d0e5952c..1f55bfcf 100644 --- a/src/mcd-connection.c +++ b/src/mcd-connection.c @@ -118,7 +118,6 @@ struct _McdConnectionPrivate guint setting_avatar : 1; guint has_presence_if : 1; guint has_avatars_if : 1; - guint has_alias_if : 1; guint has_capabilities_if : 1; guint has_contact_capabilities_draft1_if : 1; guint has_contact_capabilities_if : 1; @@ -141,8 +140,6 @@ struct _McdConnectionPrivate /* FALSE until connected and the supported presence statuses retrieved */ guint presence_info_ready : 1; - gchar *alias; - gboolean is_disposed; }; @@ -168,7 +165,6 @@ enum { READY, SELF_PRESENCE_CHANGED, - SELF_NICKNAME_CHANGED, CONNECTION_STATUS_CHANGED, N_SIGNALS }; @@ -881,132 +877,6 @@ _mcd_connection_setup_avatar (McdConnection *connection) g_free (mime_type); } -static void -on_aliases_changed (TpConnection *proxy, const GPtrArray *aliases, - gpointer user_data, GObject *weak_object) -{ - McdConnectionPrivate *priv = user_data; - guint self_handle; - guint i; - - DEBUG ("called"); - - self_handle = tp_connection_get_self_handle (proxy); - - for (i = 0; i < aliases->len; i++) - { - GValueArray *structure = g_ptr_array_index (aliases, i); - - if (g_value_get_uint (structure->values) == self_handle) - { - const gchar *alias = g_value_get_string (structure->values + 1); - - DEBUG ("Our alias on %s changed to %s", - tp_proxy_get_object_path (proxy), alias); - - if (priv->alias == NULL || tp_strdiff (priv->alias, alias)) - { - g_free (priv->alias); - priv->alias = g_strdup (alias); - g_signal_emit (weak_object, signals[SELF_NICKNAME_CHANGED], - 0, alias); - } - break; - } - } -} - -static void -aliasing_set_aliases_cb (TpConnection *proxy, const GError *error, - gpointer user_data, GObject *weak_object) -{ - if (error) - { - g_warning ("%s: error: %s", G_STRFUNC, error->message); - } -} - -void -_mcd_connection_set_nickname (McdConnection *connection, - const gchar *nickname) -{ - McdConnectionPrivate *priv = connection->priv; - GHashTable *aliases; - TpHandle self_handle; - - if (!priv->has_alias_if) - return; - - DEBUG ("setting nickname '%s' using Aliasing", nickname); - - aliases = g_hash_table_new (NULL, NULL); - self_handle = tp_connection_get_self_handle (priv->tp_conn); - g_hash_table_insert (aliases, GUINT_TO_POINTER (self_handle), - (gchar *) nickname); - tp_cli_connection_interface_aliasing_call_set_aliases (priv->tp_conn, -1, - aliases, - aliasing_set_aliases_cb, - priv, NULL, - (GObject *)connection); - g_hash_table_destroy (aliases); -} - -static void -_mcd_connection_get_aliases_cb (TpConnection *proxy, - GHashTable *aliases, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - McdConnectionPrivate *priv = user_data; - guint self_handle; - const gchar *alias; - - DEBUG ("called"); - - if (error != NULL) - { - DEBUG ("GetAliases([SelfHandle]) failed: %s", error->message); - return; - } - - self_handle = tp_connection_get_self_handle (proxy); - - alias = g_hash_table_lookup (aliases,GUINT_TO_POINTER (self_handle)); - - if (alias != NULL && - (priv->alias == NULL || tp_strdiff (priv->alias, alias))) - { - g_free (priv->alias); - priv->alias = g_strdup (alias); - g_signal_emit (weak_object, signals[SELF_NICKNAME_CHANGED], 0, - alias); - } -} - -static void -_mcd_connection_setup_alias (McdConnection *connection) -{ - McdConnectionPrivate *priv = connection->priv; - GArray *self_handle_array; - guint self_handle; - - self_handle_array = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); - self_handle = tp_connection_get_self_handle (priv->tp_conn); - g_array_append_val (self_handle_array, self_handle); - - tp_cli_connection_interface_aliasing_connect_to_aliases_changed (priv->tp_conn, - on_aliases_changed, - priv, NULL, - (GObject *)connection, - NULL); - - tp_cli_connection_interface_aliasing_call_get_aliases - (priv->tp_conn, -1, self_handle_array, _mcd_connection_get_aliases_cb, - priv, NULL, (GObject *) connection); - g_array_free (self_handle_array, TRUE); -} - static gboolean mcd_connection_reconnect (McdConnection *connection) { @@ -1533,8 +1403,6 @@ on_connection_ready (TpConnection *tp_conn, const GError *error, (tp_conn, TP_IFACE_QUARK_CONNECTION_INTERFACE_SIMPLE_PRESENCE); priv->has_avatars_if = tp_proxy_has_interface_by_id (tp_conn, TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS); - priv->has_alias_if = tp_proxy_has_interface_by_id (tp_conn, - TP_IFACE_QUARK_CONNECTION_INTERFACE_ALIASING); priv->has_capabilities_if = tp_proxy_has_interface_by_id (tp_conn, TP_IFACE_QUARK_CONNECTION_INTERFACE_CAPABILITIES); priv->has_contact_capabilities_draft1_if = tp_proxy_has_interface_by_id (tp_conn, @@ -1554,9 +1422,6 @@ on_connection_ready (TpConnection *tp_conn, const GError *error, if (priv->has_avatars_if) _mcd_connection_setup_avatar (connection); - if (priv->has_alias_if) - _mcd_connection_setup_alias (connection); - if (!priv->dispatching_started) _mcd_dispatcher_add_connection (priv->dispatcher, connection); |