summaryrefslogtreecommitdiff
path: root/telepathy-glib/text-channel.c
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.co.uk>2012-04-27 14:32:10 +0200
committerXavier Claessens <xavier.claessens@collabora.co.uk>2012-05-09 18:10:41 +0200
commit9544a1997eed04aecef4ed98ddf776c2759b28b9 (patch)
tree69e4878adb308161e5f774991e8680d006d25ec4 /telepathy-glib/text-channel.c
parent76205ffed60d37618e04c479299c09ee497dcd15 (diff)
downloadtelepathy-glib-9544a1997eed04aecef4ed98ddf776c2759b28b9.tar.gz
Move ChatState to TpTextChannel
API on TpChannel is now deprecated but still used to implement the corresponding API on TpTextChannel. https://bugs.freedesktop.org/show_bug.cgi?id=49215
Diffstat (limited to 'telepathy-glib/text-channel.c')
-rw-r--r--telepathy-glib/text-channel.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/telepathy-glib/text-channel.c b/telepathy-glib/text-channel.c
index 387bac17f..adf5ca09e 100644
--- a/telepathy-glib/text-channel.c
+++ b/telepathy-glib/text-channel.c
@@ -103,6 +103,7 @@ enum /* signals */
SIG_MESSAGE_RECEIVED,
SIG_PENDING_MESSAGE_REMOVED,
SIG_MESSAGE_SENT,
+ SIG_CONTACT_CHAT_STATE_CHANGED,
LAST_SIGNAL
};
@@ -359,6 +360,42 @@ message_sent_cb (TpChannel *channel,
}
static void
+chat_state_changed_cb (TpTextChannel *self,
+ TpHandle handle,
+ TpChannelChatState state)
+{
+ TpConnection *conn;
+ TpContact *contact;
+
+ /* We have only an handle, but since we guarantee "contact-chat-state-changed"
+ * to be emitted only if TP_CHANNEL_FEATURE_GROUP and
+ * TP_CHANNEL_FEATURE_CONTACTS has been prepared, we should already have its
+ * TpContact. If the TpContact does not exist, telling its chat state is
+ * useless anyway. */
+ conn = tp_channel_borrow_connection ((TpChannel *) self);
+ contact = tp_connection_dup_contact_if_possible (conn, handle, NULL);
+ if (contact == NULL)
+ return;
+
+ g_signal_emit (self, signals[SIG_CONTACT_CHAT_STATE_CHANGED], 0,
+ contact, state);
+
+ g_object_unref (contact);
+}
+
+static void
+tp_text_channel_prepare_chat_states_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ /* This feature depends on TP_CHANNEL_FEATURE_CHAT_STATES so it's already
+ * prepared. */
+ tp_simple_async_report_success_in_idle ((GObject *) proxy,
+ callback, user_data, tp_text_channel_prepare_chat_states_async);
+}
+
+static void
tp_text_channel_constructed (GObject *obj)
{
TpTextChannel *self = (TpTextChannel *) obj;
@@ -399,6 +436,11 @@ tp_text_channel_constructed (GObject *obj)
}
+ /* Forward TpChannel::chat-state-changed as
+ * TpTextChannel::contact-chat-state-changed */
+ g_signal_connect (self, "chat-state-changed",
+ G_CALLBACK (chat_state_changed_cb), NULL);
+
props = tp_channel_borrow_immutable_properties (TP_CHANNEL (self));
self->priv->supported_content_types = (GStrv) tp_asv_get_strv (props,
@@ -802,6 +844,7 @@ tp_text_channel_prepare_sms_async (TpProxy *proxy,
enum {
FEAT_PENDING_MESSAGES,
FEAT_SMS,
+ FEAT_CHAT_STATES,
N_FEAT
};
@@ -810,6 +853,7 @@ tp_text_channel_list_features (TpProxyClass *cls G_GNUC_UNUSED)
{
static TpProxyFeature features[N_FEAT + 1] = { { 0 } };
static GQuark need_sms[2] = {0, 0};
+ static GQuark depends_chat_state[2] = {0, 0};
if (G_LIKELY (features[0].name != 0))
return features;
@@ -826,6 +870,13 @@ tp_text_channel_list_features (TpProxyClass *cls G_GNUC_UNUSED)
need_sms[0] = TP_IFACE_QUARK_CHANNEL_INTERFACE_SMS;
features[FEAT_SMS].interfaces_needed = need_sms;
+ features[FEAT_CHAT_STATES].name =
+ TP_TEXT_CHANNEL_FEATURE_CHAT_STATES;
+ features[FEAT_CHAT_STATES].prepare_async =
+ tp_text_channel_prepare_chat_states_async;
+ depends_chat_state[0] = TP_CHANNEL_FEATURE_CHAT_STATES;
+ features[FEAT_CHAT_STATES].depends_on = depends_chat_state;
+
/* assert that the terminator at the end is there */
g_assert (features[N_FEAT].name == 0);
@@ -1025,6 +1076,26 @@ tp_text_channel_class_init (TpTextChannelClass *klass)
3, TP_TYPE_SIGNALLED_MESSAGE, G_TYPE_UINT, G_TYPE_STRING);
g_type_class_add_private (gobject_class, sizeof (TpTextChannelPrivate));
+
+ /**
+ * TpTextChannel::contact-chat-state-changed:
+ * @self: a channel
+ * @contact: a #TpContact for the local user or another contact
+ * @state: the new #TpChannelChatState for the contact
+ *
+ * Emitted when a contact's chat state changes after tp_proxy_prepare_async()
+ * has finished preparing features %TP_TEXT_CHANNEL_FEATURE_CHAT_STATES,
+ * %TP_CHANNEL_FEATURE_GROUP and %TP_CHANNEL_FEATURE_CONTACTS.
+ *
+ * Since: 0.UNRELEASED
+ */
+ signals[SIG_CONTACT_CHAT_STATE_CHANGED] = g_signal_new (
+ "contact-chat-state-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 2, TP_TYPE_CONTACT, G_TYPE_UINT);
}
static void
@@ -1494,6 +1565,53 @@ tp_text_channel_ack_message_finish (TpTextChannel *self,
_tp_implement_finish_void (self, tp_text_channel_ack_message_async)
}
+/**
+ * TP_TEXT_CHANNEL_FEATURE_CHAT_STATES:
+ *
+ * Expands to a call to a function that returns a quark representing the
+ * chat states feature on a #TpTextChannel.
+ *
+ * When this feature is prepared, tp_text_channel_get_chat_state() and the
+ * #TpTextChannel::contact-chat-state-changed signal become useful.
+ *
+ * One can ask for a feature to be prepared using the
+ * tp_proxy_prepare_async() function, and waiting for it to callback.
+ *
+ * Since: 0.UNRELEASED
+ */
+
+GQuark
+tp_text_channel_get_feature_quark_chat_states (void)
+{
+ return g_quark_from_static_string ("tp-text-channel-feature-chat-states");
+}
+
+/**
+ * tp_text_channel_get_chat_state:
+ * @self: a channel
+ * @contact: a #TpContact
+ *
+ * Return the chat state for the given contact. If tp_proxy_is_prepared()
+ * would return %FALSE for the feature %TP_TEXT_CHANNEL_FEATURE_CHAT_STATES,
+ * the result will always be %TP_CHANNEL_CHAT_STATE_INACTIVE.
+ *
+ * Returns: the chat state for @contact, or %TP_CHANNEL_CHAT_STATE_INACTIVE
+ * if their chat state is not known
+ * Since: 0.UNRELEASED
+ */
+TpChannelChatState
+tp_text_channel_get_chat_state (TpTextChannel *self,
+ TpContact *contact)
+{
+ g_return_val_if_fail (TP_IS_TEXT_CHANNEL (self), 0);
+
+ /* Use the deprecated function internally to avoid duplicated introspection */
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ return tp_channel_get_chat_state ((TpChannel *) self,
+ tp_contact_get_handle (contact));
+ G_GNUC_END_IGNORE_DEPRECATIONS
+}
+
static void
set_chat_state_cb (TpChannel *proxy,
const GError *error,