aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-10-17 22:40:12 +0800
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-10-17 22:40:37 +0800
commit83f9dd20c3238784c46072aa134741d9fe7ee3b6 (patch)
tree209a5f5ef609653fc57cf4e509e3f9df46b53ad0 /libempathy
parent019f7e6ea56c0967427f5f2d6932dafa4bd80445 (diff)
downloadgsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.tar
gsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.tar.gz
gsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.tar.bz2
gsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.tar.lz
gsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.tar.xz
gsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.tar.zst
gsoc2013-empathy-83f9dd20c3238784c46072aa134741d9fe7ee3b6.zip
Revert "TpChat: remove support for old Properties"
This reverts commit 0e053c39298d88afa1645c0d95a8aa43b662cc38.
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/empathy-tp-chat.c268
1 files changed, 263 insertions, 5 deletions
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index cfa93147d..2285f3f42 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -38,6 +38,13 @@
#define DEBUG_FLAG EMPATHY_DEBUG_TP | EMPATHY_DEBUG_CHAT
#include "empathy-debug.h"
+typedef struct {
+ gchar *name;
+ guint id;
+ TpPropertyFlags flags;
+ GValue *value;
+} EmpathyTpChatProperty;
+
struct _EmpathyTpChatPrivate {
TpAccount *account;
EmpathyContact *user;
@@ -47,6 +54,8 @@ struct _EmpathyTpChatPrivate {
GQueue *messages_queue;
/* Queue of messages signalled but not acked yet */
GQueue *pending_messages_queue;
+ gboolean had_properties_list;
+ GPtrArray *properties;
/* Subject */
gboolean supports_subject;
@@ -594,6 +603,214 @@ list_pending_messages (EmpathyTpChat *self)
}
static void
+tp_chat_property_flags_changed_cb (TpProxy *proxy,
+ const GPtrArray *properties,
+ gpointer user_data,
+ GObject *chat)
+{
+ EmpathyTpChat *self = (EmpathyTpChat *) chat;
+ guint i, j;
+
+ if (!self->priv->had_properties_list || !properties) {
+ return;
+ }
+
+ for (i = 0; i < properties->len; i++) {
+ GValueArray *prop_struct;
+ EmpathyTpChatProperty *property;
+ guint id;
+ guint flags;
+
+ prop_struct = g_ptr_array_index (properties, i);
+ id = g_value_get_uint (g_value_array_get_nth (prop_struct, 0));
+ flags = g_value_get_uint (g_value_array_get_nth (prop_struct, 1));
+
+ for (j = 0; j < self->priv->properties->len; j++) {
+ property = g_ptr_array_index (self->priv->properties, j);
+ if (property->id == id) {
+ property->flags = flags;
+ DEBUG ("property %s flags changed: %d",
+ property->name, property->flags);
+
+ if (!tp_strdiff (property->name, "subject")) {
+ self->priv->can_set_subject = !!(property->flags & TP_PROPERTY_FLAG_WRITE);
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void
+tp_chat_properties_changed_cb (TpProxy *proxy,
+ const GPtrArray *properties,
+ gpointer user_data,
+ GObject *chat)
+{
+ EmpathyTpChat *self = (EmpathyTpChat *) chat;
+ EmpathyTpChatPrivate *priv = self->priv;
+ guint i, j;
+
+ if (!self->priv->had_properties_list || !properties) {
+ return;
+ }
+
+ for (i = 0; i < properties->len; i++) {
+ GValueArray *prop_struct;
+ EmpathyTpChatProperty *property;
+ guint id;
+ GValue *src_value;
+
+ prop_struct = g_ptr_array_index (properties, i);
+ id = g_value_get_uint (g_value_array_get_nth (prop_struct, 0));
+ src_value = g_value_get_boxed (g_value_array_get_nth (prop_struct, 1));
+
+ for (j = 0; j < self->priv->properties->len; j++) {
+ property = g_ptr_array_index (self->priv->properties, j);
+ if (property->id == id) {
+ if (property->value) {
+ g_value_copy (src_value, property->value);
+ } else {
+ property->value = tp_g_value_slice_dup (src_value);
+ }
+
+ DEBUG ("property %s changed", property->name);
+
+ if (!tp_strdiff (property->name, "name") &&
+ G_VALUE_HOLDS_STRING (property->value)) {
+ g_free (priv->title);
+ priv->title = g_value_dup_string (property->value);
+ g_object_notify (chat, "title");
+ } else if (!tp_strdiff (property->name, "subject") &&
+ G_VALUE_HOLDS_STRING (property->value)) {
+ priv->supports_subject = TRUE;
+ priv->can_set_subject = !!(property->flags & TP_PROPERTY_FLAG_WRITE);
+ g_free (priv->subject);
+ priv->subject = g_value_dup_string (property->value);
+ g_object_notify (chat, "subject");
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+static void
+tp_chat_get_properties_cb (TpProxy *proxy,
+ const GPtrArray *properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *chat)
+{
+ if (error) {
+ DEBUG ("Error getting properties: %s", error->message);
+ return;
+ }
+
+ tp_chat_properties_changed_cb (proxy, properties, user_data, chat);
+}
+
+static void
+tp_chat_list_properties_cb (TpProxy *proxy,
+ const GPtrArray *properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *chat)
+{
+ EmpathyTpChat *self = (EmpathyTpChat *) chat;
+ GArray *ids;
+ guint i;
+
+ if (error) {
+ DEBUG ("Error listing properties: %s", error->message);
+ return;
+ }
+
+ self->priv->had_properties_list = TRUE;
+
+ ids = g_array_sized_new (FALSE, FALSE, sizeof (guint), properties->len);
+ self->priv->properties = g_ptr_array_sized_new (properties->len);
+ for (i = 0; i < properties->len; i++) {
+ GValueArray *prop_struct;
+ EmpathyTpChatProperty *property;
+
+ prop_struct = g_ptr_array_index (properties, i);
+ property = g_slice_new0 (EmpathyTpChatProperty);
+ property->id = g_value_get_uint (g_value_array_get_nth (prop_struct, 0));
+ property->name = g_value_dup_string (g_value_array_get_nth (prop_struct, 1));
+ property->flags = g_value_get_uint (g_value_array_get_nth (prop_struct, 3));
+
+ DEBUG ("Adding property name=%s id=%d flags=%d",
+ property->name, property->id, property->flags);
+ g_ptr_array_add (self->priv->properties, property);
+ if (property->flags & TP_PROPERTY_FLAG_READ) {
+ g_array_append_val (ids, property->id);
+ }
+ }
+
+ tp_cli_properties_interface_call_get_properties (proxy, -1,
+ ids,
+ tp_chat_get_properties_cb,
+ NULL, NULL,
+ chat);
+
+ g_array_free (ids, TRUE);
+}
+
+static void
+empathy_tp_chat_set_property (EmpathyTpChat *self,
+ const gchar *name,
+ const GValue *value)
+{
+ EmpathyTpChatProperty *property;
+ guint i;
+
+ if (!self->priv->had_properties_list) {
+ return;
+ }
+
+ for (i = 0; i < self->priv->properties->len; i++) {
+ property = g_ptr_array_index (self->priv->properties, i);
+ if (!tp_strdiff (property->name, name)) {
+ GPtrArray *properties;
+ GValueArray *prop;
+ GValue id = {0, };
+ GValue dest_value = {0, };
+
+ if (!(property->flags & TP_PROPERTY_FLAG_WRITE)) {
+ break;
+ }
+
+ g_value_init (&id, G_TYPE_UINT);
+ g_value_init (&dest_value, G_TYPE_VALUE);
+ g_value_set_uint (&id, property->id);
+ g_value_set_boxed (&dest_value, value);
+
+ prop = g_value_array_new (2);
+ g_value_array_append (prop, &id);
+ g_value_array_append (prop, &dest_value);
+
+ properties = g_ptr_array_sized_new (1);
+ g_ptr_array_add (properties, prop);
+
+ DEBUG ("Set property %s", name);
+ tp_cli_properties_interface_call_set_properties (self, -1,
+ properties,
+ (tp_cli_properties_interface_callback_for_set_properties)
+ tp_chat_async_cb,
+ "Seting property", NULL,
+ G_OBJECT (self));
+
+ g_ptr_array_free (properties, TRUE);
+ g_value_array_free (prop);
+
+ break;
+ }
+ }
+}
+
+static void
update_subject (EmpathyTpChat *self,
GHashTable *properties)
{
@@ -693,11 +910,21 @@ void
empathy_tp_chat_set_subject (EmpathyTpChat *self,
const gchar *subject)
{
- tp_cli_channel_interface_subject_call_set_subject (TP_CHANNEL (self), -1,
- subject,
- tp_chat_async_cb,
- "while setting subject", NULL,
- G_OBJECT (self));
+ if (tp_proxy_has_interface_by_id (self,
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_SUBJECT)) {
+ tp_cli_channel_interface_subject_call_set_subject (TP_CHANNEL (self), -1,
+ subject,
+ tp_chat_async_cb,
+ "while setting subject", NULL,
+ G_OBJECT (self));
+ } else {
+ GValue value = { 0, };
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, subject);
+ empathy_tp_chat_set_property (self, "subject", &value);
+ g_value_unset (&value);
+ }
}
const gchar *
@@ -758,9 +985,24 @@ static void
tp_chat_finalize (GObject *object)
{
EmpathyTpChat *self = (EmpathyTpChat *) object;
+ guint i;
DEBUG ("Finalize: %p", object);
+ if (self->priv->properties) {
+ for (i = 0; i < self->priv->properties->len; i++) {
+ EmpathyTpChatProperty *property;
+
+ property = g_ptr_array_index (self->priv->properties, i);
+ g_free (property->name);
+ if (property->value) {
+ tp_g_value_slice_free (property->value);
+ }
+ g_slice_free (EmpathyTpChatProperty, property);
+ }
+ g_ptr_array_free (self->priv->properties, TRUE);
+ }
+
g_queue_free (self->priv->messages_queue);
g_queue_free (self->priv->pending_messages_queue);
g_hash_table_destroy (self->priv->messages_being_sent);
@@ -1624,6 +1866,22 @@ tp_chat_prepare_ready_async (TpProxy *proxy,
}
if (tp_proxy_has_interface_by_id (self,
+ TP_IFACE_QUARK_PROPERTIES_INTERFACE)) {
+ tp_cli_properties_interface_call_list_properties (channel, -1,
+ tp_chat_list_properties_cb,
+ NULL, NULL,
+ G_OBJECT (self));
+ tp_cli_properties_interface_connect_to_properties_changed (channel,
+ tp_chat_properties_changed_cb,
+ NULL, NULL,
+ G_OBJECT (self), NULL);
+ tp_cli_properties_interface_connect_to_property_flags_changed (channel,
+ tp_chat_property_flags_changed_cb,
+ NULL, NULL,
+ G_OBJECT (self), NULL);
+ }
+
+ if (tp_proxy_has_interface_by_id (self,
TP_IFACE_QUARK_CHANNEL_INTERFACE_SUBJECT)) {
tp_cli_dbus_properties_call_get_all (channel, -1,
TP_IFACE_CHANNEL_INTERFACE_SUBJECT,