#include "empathy-tp-chat.h"
#include "empathy-tp-contact-factory.h"
#include "empathy-contact-list.h"
-#include "empathy-marshal.h"
#include "empathy-request-util.h"
#include "empathy-time.h"
#include "empathy-utils.h"
GQueue *messages_queue;
/* Queue of messages signalled but not acked yet */
GQueue *pending_messages_queue;
- gboolean had_properties_list;
- GPtrArray *properties;
- TpChannelPasswordFlags password_flags;
- /* TRUE if we fetched the password flag of the channel or if it's not needed
- * (channel doesn't implement the Password interface) */
- gboolean got_password_flags;
+
+ /* Subject */
+ gboolean supports_subject;
+ gboolean can_set_subject;
+ gchar *subject;
+
+ /* Room config (for now, we only track the title and don't support
+ * setting it) */
+ gchar *title;
+
gboolean can_upgrade_to_muc;
- gboolean got_sms_channel;
- gboolean sms_channel;
GHashTable *messages_being_sent;
PROP_0,
PROP_ACCOUNT,
PROP_REMOTE_CONTACT,
- PROP_PASSWORD_NEEDED,
- PROP_SMS_CHANNEL,
PROP_N_MESSAGES_SENDING,
+ PROP_TITLE,
+ PROP_SUBJECT,
};
enum {
MESSAGE_RECEIVED,
SEND_ERROR,
CHAT_STATE_CHANGED,
- PROPERTY_CHANGED,
MESSAGE_ACKNOWLEDGED,
LAST_SIGNAL
};
tp_chat_set_delivery_status (self, delivery_token,
EMPATHY_DELIVERY_STATUS_NONE);
goto out;
- } else if (delivery_status != TP_DELIVERY_STATUS_PERMANENTLY_FAILED) {
+ } else if (delivery_status != TP_DELIVERY_STATUS_PERMANENTLY_FAILED &&
+ delivery_status != TP_DELIVERY_STATUS_TEMPORARILY_FAILED) {
goto out;
}
* TpMessage. (fdo #35884) */
echo = tp_asv_get_boxed (header, "delivery-echo",
TP_ARRAY_TYPE_MESSAGE_PART_LIST);
- if (echo != NULL && echo->len >= 1) {
+ if (echo != NULL && echo->len >= 2) {
const GHashTable *echo_body;
echo_body = g_ptr_array_index (echo, 1);
}
static void
-tp_chat_property_flags_changed_cb (TpProxy *proxy,
- const GPtrArray *properties,
- gpointer user_data,
- GObject *chat)
+update_subject (EmpathyTpChat *self,
+ GHashTable *properties)
{
- EmpathyTpChat *self = (EmpathyTpChat *) chat;
- guint i, j;
+ EmpathyTpChatPrivate *priv = self->priv;
+ gboolean can_set, valid;
+ const gchar *subject;
- if (!self->priv->had_properties_list || !properties) {
- return;
+ can_set = tp_asv_get_boolean (properties, "CanSet", &valid);
+ if (valid) {
+ priv->can_set_subject = can_set;
}
- 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);
- break;
- }
- }
+ subject = tp_asv_get_string (properties, "Subject");
+ if (subject != NULL) {
+ g_free (priv->subject);
+ priv->subject = g_strdup (subject);
+ g_object_notify (G_OBJECT (self), "subject");
}
+
+ /* TODO: track Actor and Timestamp. */
}
static void
-tp_chat_properties_changed_cb (TpProxy *proxy,
- const GPtrArray *properties,
- gpointer user_data,
- GObject *chat)
+tp_chat_get_all_subject_cb (TpProxy *proxy,
+ GHashTable *properties,
+ const GError *error,
+ gpointer user_data G_GNUC_UNUSED,
+ GObject *chat)
{
- EmpathyTpChat *self = (EmpathyTpChat *) chat;
- guint i, j;
+ EmpathyTpChat *self = EMPATHY_TP_CHAT (chat);
+ EmpathyTpChatPrivate *priv = self->priv;
- if (!self->priv->had_properties_list || !properties) {
+ if (error) {
+ DEBUG ("Error fetching subject: %s", error->message);
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);
- g_signal_emit (chat, signals[PROPERTY_CHANGED], 0,
- property->name, property->value);
- break;
- }
+ priv->supports_subject = TRUE;
+ update_subject (self, properties);
+}
+
+static void
+update_title (EmpathyTpChat *self,
+ GHashTable *properties)
+{
+ EmpathyTpChatPrivate *priv = self->priv;
+ const gchar *title = tp_asv_get_string (properties, "Title");
+
+ if (title != NULL) {
+ if (tp_str_empty (title)) {
+ title = NULL;
}
+
+ g_free (priv->title);
+ priv->title = g_strdup (title);
+ g_object_notify (G_OBJECT (self), "title");
}
}
static void
-tp_chat_get_properties_cb (TpProxy *proxy,
- const GPtrArray *properties,
- const GError *error,
- gpointer user_data,
- GObject *chat)
+tp_chat_get_all_room_config_cb (TpProxy *proxy,
+ GHashTable *properties,
+ const GError *error,
+ gpointer user_data G_GNUC_UNUSED,
+ GObject *chat)
{
+ EmpathyTpChat *self = EMPATHY_TP_CHAT (chat);
+
if (error) {
- DEBUG ("Error getting properties: %s", error->message);
+ DEBUG ("Error fetching room config: %s", error->message);
return;
}
- tp_chat_properties_changed_cb (proxy, properties, user_data, chat);
+ update_title (self, properties);
}
static void
-tp_chat_list_properties_cb (TpProxy *proxy,
- const GPtrArray *properties,
- const GError *error,
- gpointer user_data,
- GObject *chat)
+tp_chat_dbus_properties_changed_cb (TpProxy *proxy,
+ const gchar *interface_name,
+ GHashTable *changed,
+ const gchar **invalidated,
+ gpointer user_data,
+ GObject *chat)
{
- EmpathyTpChat *self = (EmpathyTpChat *) chat;
- GArray *ids;
- guint i;
-
- self->priv->had_properties_list = TRUE;
+ EmpathyTpChat *self = EMPATHY_TP_CHAT (chat);
- if (error) {
- DEBUG ("Error listing properties: %s", error->message);
- return;
+ if (!tp_strdiff (interface_name, TP_IFACE_CHANNEL_INTERFACE_SUBJECT)) {
+ update_subject (self, changed);
}
- 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);
- }
+ if (!tp_strdiff (interface_name, TP_IFACE_CHANNEL_INTERFACE_ROOM_CONFIG)) {
+ update_title (self, changed);
}
-
- tp_cli_properties_interface_call_get_properties (proxy, -1,
- ids,
- tp_chat_get_properties_cb,
- NULL, NULL,
- chat);
-
- g_array_free (ids, TRUE);
}
void
-empathy_tp_chat_set_property (EmpathyTpChat *self,
- const gchar *name,
- const GValue *value)
+empathy_tp_chat_set_subject (EmpathyTpChat *self,
+ const gchar *subject)
{
- 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));
+ tp_cli_channel_interface_subject_call_set_subject (TP_CHANNEL (self), -1,
+ subject,
+ tp_chat_async_cb,
+ "while setting subject", NULL,
+ G_OBJECT (self));
+}
- g_ptr_array_free (properties, TRUE);
- g_value_array_free (prop);
+const gchar *
+empathy_tp_chat_get_title (EmpathyTpChat *self)
+{
+ EmpathyTpChatPrivate *priv = self->priv;
- break;
- }
- }
+ return priv->title;
}
-EmpathyTpChatProperty *
-empathy_tp_chat_get_property (EmpathyTpChat *self,
- const gchar *name)
+gboolean
+empathy_tp_chat_supports_subject (EmpathyTpChat *self)
{
- EmpathyTpChatProperty *property;
- guint i;
+ EmpathyTpChatPrivate *priv = self->priv;
- if (!self->priv->had_properties_list) {
- return NULL;
- }
+ return priv->supports_subject;
+}
- for (i = 0; i < self->priv->properties->len; i++) {
- property = g_ptr_array_index (self->priv->properties, i);
- if (!tp_strdiff (property->name, name)) {
- return property;
- }
- }
+gboolean
+empathy_tp_chat_can_set_subject (EmpathyTpChat *self)
+{
+ EmpathyTpChatPrivate *priv = self->priv;
- return NULL;
+ return priv->can_set_subject;
}
-GPtrArray *
-empathy_tp_chat_get_properties (EmpathyTpChat *self)
+const gchar *
+empathy_tp_chat_get_subject (EmpathyTpChat *self)
{
- return self->priv->properties;
+ EmpathyTpChatPrivate *priv = self->priv;
+
+ return priv->subject;
}
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);
+ g_hash_table_unref (self->priv->messages_being_sent);
+
+ g_free (self->priv->title);
+ g_free (self->priv->subject);
G_OBJECT_CLASS (empathy_tp_chat_parent_class)->finalize (object);
}
static void
check_almost_ready (EmpathyTpChat *self)
{
+ TpChannel *channel = (TpChannel *) self;
+
if (self->priv->ready_result == NULL)
return;
if (self->priv->user == NULL)
return;
- if (!self->priv->got_password_flags)
- return;
-
- if (!self->priv->got_sms_channel)
- return;
-
/* We need either the members (room) or the remote contact (private chat).
* If the chat is protected by a password we can't get these information so
* consider the chat as ready so it can be presented to the user. */
- if (!empathy_tp_chat_password_needed (self) && self->priv->members == NULL &&
+ if (!tp_channel_password_needed (channel) && self->priv->members == NULL &&
self->priv->remote_contact == NULL)
return;
check_ready (self);
}
-static void
-tp_chat_update_remote_contact (EmpathyTpChat *self)
-{
- TpChannel *channel = (TpChannel *) self;
- EmpathyContact *contact = NULL;
- TpHandle self_handle;
- TpHandleType handle_type;
- GList *l;
-
- /* If this is a named chatroom, never pretend it is a private chat */
- tp_channel_get_handle (channel, &handle_type);
- if (handle_type == TP_HANDLE_TYPE_ROOM) {
- return;
- }
-
- /* This is an MSN chat, but it's the new style where 1-1 chats don't
- * have the group interface. If it has the conference interface, then
- * it is indeed a MUC. */
- if (tp_proxy_has_interface_by_id (self,
- TP_IFACE_QUARK_CHANNEL_INTERFACE_CONFERENCE)) {
- return;
- }
-
- /* This is an MSN-like chat where anyone can join the chat at anytime.
- * If there is only one non-self contact member, we are in a private
- * chat and we set the "remote-contact" property to that contact. If
- * there are more, set the "remote-contact" property to NULL and the
- * UI will display a contact list. */
- self_handle = tp_channel_group_get_self_handle (channel);
- for (l = self->priv->members; l; l = l->next) {
- /* Skip self contact if member */
- if (empathy_contact_get_handle (l->data) == self_handle) {
- continue;
- }
-
- /* We have more than one remote contact, break */
- if (contact != NULL) {
- contact = NULL;
- break;
- }
-
- /* If we didn't find yet a remote contact, keep this one */
- contact = l->data;
- }
-
- if (self->priv->remote_contact == contact) {
- return;
- }
-
- DEBUG ("Changing remote contact from %p to %p",
- self->priv->remote_contact, contact);
-
- if (self->priv->remote_contact) {
- g_object_unref (self->priv->remote_contact);
- }
-
- self->priv->remote_contact = contact ? g_object_ref (contact) : NULL;
- g_object_notify (G_OBJECT (self), "remote-contact");
-}
-
static void
tp_chat_got_added_contacts_cb (TpConnection *connection,
guint n_contacts,
}
}
- tp_chat_update_remote_contact (EMPATHY_TP_CHAT (chat));
check_almost_ready (EMPATHY_TP_CHAT (chat));
}
self->priv->user = g_object_ref (new);
}
- tp_chat_update_remote_contact (self);
check_almost_ready (self);
}
G_OBJECT (self));
}
- tp_chat_update_remote_contact (self);
-
if (actor_contact != NULL) {
g_object_unref (actor_contact);
}
check_almost_ready (self);
}
-static void
-password_flags_changed_cb (TpChannel *channel,
- guint added,
- guint removed,
- gpointer user_data,
- GObject *weak_object)
-{
- EmpathyTpChat *self = EMPATHY_TP_CHAT (weak_object);
- gboolean was_needed, needed;
-
- was_needed = empathy_tp_chat_password_needed (self);
-
- self->priv->password_flags |= added;
- self->priv->password_flags ^= removed;
-
- needed = empathy_tp_chat_password_needed (self);
-
- if (was_needed != needed)
- g_object_notify (G_OBJECT (self), "password-needed");
-}
-
-static void
-got_password_flags_cb (TpChannel *proxy,
- guint password_flags,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- EmpathyTpChat *self = EMPATHY_TP_CHAT (weak_object);
-
- self->priv->got_password_flags = TRUE;
- self->priv->password_flags = password_flags;
-
- check_almost_ready (EMPATHY_TP_CHAT (self));
-}
-
-static void
-sms_channel_changed_cb (TpChannel *channel,
- gboolean sms_channel,
- gpointer user_data,
- GObject *chat)
-{
- EmpathyTpChat *self = (EmpathyTpChat *) chat;
-
- self->priv->sms_channel = sms_channel;
-
- g_object_notify (G_OBJECT (chat), "sms-channel");
-}
-
-static void
-get_sms_channel_cb (TpProxy *channel,
- const GValue *value,
- const GError *in_error,
- gpointer user_data,
- GObject *chat)
-{
- EmpathyTpChat *self = (EmpathyTpChat *) chat;
-
- if (in_error != NULL) {
- DEBUG ("Failed to get SMSChannel: %s", in_error->message);
- return;
- }
-
- g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
-
- self->priv->sms_channel = g_value_get_boolean (value);
- self->priv->got_sms_channel = TRUE;
-
- check_almost_ready (EMPATHY_TP_CHAT (chat));
-}
-
static void
tp_chat_get_property (GObject *object,
guint param_id,
case PROP_REMOTE_CONTACT:
g_value_set_object (value, self->priv->remote_contact);
break;
- case PROP_PASSWORD_NEEDED:
- g_value_set_boolean (value, empathy_tp_chat_password_needed (self));
- break;
- case PROP_SMS_CHANNEL:
- g_value_set_boolean (value, self->priv->sms_channel);
- break;
case PROP_N_MESSAGES_SENDING:
g_value_set_uint (value,
g_hash_table_size (self->priv->messages_being_sent));
break;
+ case PROP_TITLE:
+ g_value_set_string (value,
+ empathy_tp_chat_get_title (self));
+ break;
+ case PROP_SUBJECT:
+ g_value_set_string (value,
+ empathy_tp_chat_get_subject (self));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
EMPATHY_TYPE_CONTACT,
G_PARAM_READABLE));
- g_object_class_install_property (object_class,
- PROP_PASSWORD_NEEDED,
- g_param_spec_boolean ("password-needed",
- "password needed",
- "TRUE if a password is needed to join the channel",
- FALSE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_SMS_CHANNEL,
- g_param_spec_boolean ("sms-channel",
- "SMS Channel",
- "TRUE if channel is for sending SMSes",
- FALSE,
- G_PARAM_READABLE));
-
g_object_class_install_property (object_class,
PROP_N_MESSAGES_SENDING,
g_param_spec_uint ("n-messages-sending",
0, G_MAXUINT, 0,
G_PARAM_READABLE));
+ g_object_class_install_property (object_class,
+ PROP_TITLE,
+ g_param_spec_string ("title",
+ "Title",
+ "A human-readable name for the room, if any",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class,
+ PROP_SUBJECT,
+ g_param_spec_string ("subject",
+ "Subject",
+ "The room's current subject, if any",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
/* Signals */
signals[MESSAGE_RECEIVED] =
g_signal_new ("message-received-empathy",
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
+ g_cclosure_marshal_generic,
G_TYPE_NONE,
1, EMPATHY_TYPE_MESSAGE);
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _empathy_marshal_VOID__STRING_UINT_STRING,
+ g_cclosure_marshal_generic,
G_TYPE_NONE,
3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _empathy_marshal_VOID__OBJECT_UINT,
+ g_cclosure_marshal_generic,
G_TYPE_NONE,
2, EMPATHY_TYPE_CONTACT, G_TYPE_UINT);
- signals[PROPERTY_CHANGED] =
- g_signal_new ("property-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- _empathy_marshal_VOID__STRING_BOXED,
- G_TYPE_NONE,
- 2, G_TYPE_STRING, G_TYPE_VALUE);
-
signals[MESSAGE_ACKNOWLEDGED] =
g_signal_new ("message-acknowledged",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
+ g_cclosure_marshal_generic,
G_TYPE_NONE,
1, EMPATHY_TYPE_MESSAGE);
}
EmpathyTpChat *
-empathy_tp_chat_new (TpAccount *account,
+empathy_tp_chat_new (
+ TpSimpleClientFactory *factory,
+ TpAccount *account,
TpConnection *conn,
const gchar *object_path,
const GHashTable *immutable_properties)
g_return_val_if_fail (immutable_properties != NULL, NULL);
return g_object_new (EMPATHY_TYPE_TP_CHAT,
+ "factory", factory,
"account", account,
"connection", conn,
"dbus-daemon", conn_proxy->dbus_daemon,
g_free (message_body);
}
-void
-empathy_tp_chat_set_state (EmpathyTpChat *self,
- TpChannelChatState state)
-{
- g_return_if_fail (EMPATHY_IS_TP_CHAT (self));
-
- if (tp_proxy_has_interface_by_id (self,
- TP_IFACE_QUARK_CHANNEL_INTERFACE_CHAT_STATE)) {
- DEBUG ("Set state: %d", state);
- tp_cli_channel_interface_chat_state_call_set_chat_state ((TpChannel *) self, -1,
- state,
- tp_chat_async_cb,
- "setting chat state",
- NULL,
- G_OBJECT (self));
- }
-}
-
-
const GList *
empathy_tp_chat_get_pending_messages (EmpathyTpChat *self)
{
tp_msg, NULL, NULL);
}
-void
-empathy_tp_chat_acknowledge_messages (EmpathyTpChat *self,
- const GSList *messages) {
- const GSList *l;
- GList *messages_to_ack = NULL;
-
- g_return_if_fail (EMPATHY_IS_TP_CHAT (self));
-
- if (messages == NULL)
- return;
-
- for (l = messages; l != NULL; l = g_slist_next (l)) {
- EmpathyMessage *message = EMPATHY_MESSAGE (l->data);
-
- if (empathy_message_is_incoming (message)) {
- TpMessage *tp_msg = empathy_message_get_tp_message (message);
- messages_to_ack = g_list_append (messages_to_ack, tp_msg);
- }
- }
-
- if (messages_to_ack != NULL) {
- tp_text_channel_ack_messages_async (TP_TEXT_CHANNEL (self),
- messages_to_ack, NULL, NULL);
- }
-
- g_list_free (messages_to_ack);
-}
-
-void
-empathy_tp_chat_acknowledge_all_messages (EmpathyTpChat *self)
-{
- empathy_tp_chat_acknowledge_messages (self,
- (GSList *) empathy_tp_chat_get_pending_messages (self));
-}
-
-gboolean
-empathy_tp_chat_password_needed (EmpathyTpChat *self)
-{
- return self->priv->password_flags & TP_CHANNEL_PASSWORD_FLAG_PROVIDE;
-}
-
-static void
-provide_password_cb (TpChannel *channel,
- gboolean correct,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- GSimpleAsyncResult *result = user_data;
-
- if (error != NULL) {
- g_simple_async_result_set_from_error (result, error);
- }
- else if (!correct) {
- /* The current D-Bus API is a bit weird so re-use the
- * AuthenticationFailed error */
- g_simple_async_result_set_error (result, TP_ERRORS,
- TP_ERROR_AUTHENTICATION_FAILED, "Wrong password");
- }
-
- g_simple_async_result_complete (result);
- g_object_unref (result);
-}
-
-void
-empathy_tp_chat_provide_password_async (EmpathyTpChat *self,
- const gchar *password,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *result;
-
- result = g_simple_async_result_new (G_OBJECT (self),
- callback, user_data,
- empathy_tp_chat_provide_password_finish);
-
- tp_cli_channel_interface_password_call_provide_password
- ((TpChannel *) self, -1, password, provide_password_cb, result,
- NULL, G_OBJECT (self));
-}
-
-gboolean
-empathy_tp_chat_provide_password_finish (EmpathyTpChat *self,
- GAsyncResult *result,
- GError **error)
-{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- error))
- return FALSE;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result,
- G_OBJECT (self), empathy_tp_chat_provide_password_finish), FALSE);
-
- return TRUE;
-}
-
/**
* empathy_tp_chat_can_add_contact:
*
tp_cli_channel_interface_group_call_add_members ((TpChannel *) self, -1, members,
"", add_members_cb, NULL, NULL, G_OBJECT (self));
- g_array_free (members, TRUE);
+ g_array_unref (members);
}
gboolean
return self->priv->user;
}
-
-gboolean
-empathy_tp_chat_is_sms_channel (EmpathyTpChat *self)
-{
- g_return_val_if_fail (EMPATHY_IS_TP_CHAT (self), FALSE);
-
- return self->priv->sms_channel;
-}
-
GQuark
empathy_tp_chat_get_feature_ready (void)
{
}
static void
-conn_prepared_cb (GObject *source,
- GAsyncResult *result,
+tp_chat_prepare_ready_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
gpointer user_data)
{
- EmpathyTpChat *self = user_data;
- TpChannel *channel = (TpChannel *) self;
- GError *error = NULL;
- TpHandle handle;
- TpConnection *connection = (TpConnection *) source;
+ EmpathyTpChat *self = (EmpathyTpChat *) proxy;
+ TpChannel *channel = (TpChannel *) proxy;
+ TpConnection *connection;
+ gboolean listen_for_dbus_properties_changed = FALSE;
- if (!tp_proxy_prepare_finish (source, result, &error)) {
- g_simple_async_result_set_from_error (self->priv->ready_result, error);
- g_error_free (error);
- g_simple_async_result_complete (self->priv->ready_result);
- tp_clear_object (&self->priv->ready_result);
- return;
- }
+ g_assert (self->priv->ready_result == NULL);
+ self->priv->ready_result = g_simple_async_result_new (G_OBJECT (self),
+ callback, user_data, tp_chat_prepare_ready_async);
+
+ connection = tp_channel_borrow_connection (channel);
if (tp_proxy_has_interface_by_id (self,
TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) {
const TpIntSet *members;
GArray *handles;
+ TpHandle handle;
/* Get self contact from the group's self handle */
handle = tp_channel_group_get_self_handle (channel);
TpCapabilities *caps;
GPtrArray *classes;
guint i;
+ TpHandle handle;
/* Get the self contact from the connection's self handle */
handle = tp_connection_get_self_handle (connection);
}
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);
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_SUBJECT)) {
+ tp_cli_dbus_properties_call_get_all (channel, -1,
+ TP_IFACE_CHANNEL_INTERFACE_SUBJECT,
+ tp_chat_get_all_subject_cb,
+ NULL, NULL,
+ G_OBJECT (self));
+ listen_for_dbus_properties_changed = TRUE;
}
- /* Check if the chat is password protected */
if (tp_proxy_has_interface_by_id (self,
- TP_IFACE_QUARK_CHANNEL_INTERFACE_PASSWORD)) {
- self->priv->got_password_flags = FALSE;
-
- tp_cli_channel_interface_password_connect_to_password_flags_changed
- (channel, password_flags_changed_cb, self, NULL,
- G_OBJECT (self), NULL);
-
- tp_cli_channel_interface_password_call_get_password_flags
- (channel, -1, got_password_flags_cb, self, NULL, G_OBJECT (self));
- } else {
- /* No Password interface, so no need to fetch the password flags */
- self->priv->got_password_flags = TRUE;
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_ROOM_CONFIG)) {
+ tp_cli_dbus_properties_call_get_all (channel, -1,
+ TP_IFACE_CHANNEL_INTERFACE_ROOM_CONFIG,
+ tp_chat_get_all_room_config_cb,
+ NULL, NULL,
+ G_OBJECT (self));
+ listen_for_dbus_properties_changed = TRUE;
}
- /* Check if the chat is for SMS */
- if (tp_proxy_has_interface_by_id (channel,
- TP_IFACE_QUARK_CHANNEL_INTERFACE_SMS)) {
- tp_cli_channel_interface_sms_connect_to_sms_channel_changed (
- channel,
- sms_channel_changed_cb, self, NULL, G_OBJECT (self), NULL);
-
- tp_cli_dbus_properties_call_get (channel, -1,
- TP_IFACE_CHANNEL_INTERFACE_SMS, "SMSChannel",
- get_sms_channel_cb, self, NULL, G_OBJECT (self));
- } else {
- /* if there's no SMS support, then we're not waiting for it */
- self->priv->got_sms_channel = TRUE;
+ if (listen_for_dbus_properties_changed) {
+ tp_cli_dbus_properties_connect_to_properties_changed (channel,
+ tp_chat_dbus_properties_changed_cb,
+ NULL, NULL,
+ G_OBJECT (self), NULL);
}
}
-
-static void
-tp_chat_prepare_ready_async (TpProxy *proxy,
- const TpProxyFeature *feature,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- EmpathyTpChat *self = (EmpathyTpChat *) proxy;
- TpChannel *channel = (TpChannel *) proxy;
- TpConnection *connection;
- GQuark conn_features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
-
- g_assert (self->priv->ready_result == NULL);
- self->priv->ready_result = g_simple_async_result_new (G_OBJECT (self),
- callback, user_data, tp_chat_prepare_ready_async);
-
- connection = tp_channel_borrow_connection (channel);
-
- tp_proxy_prepare_async (connection, conn_features,
- conn_prepared_cb, self);
-}