[next] telepathy-glib: Move ChatState to TpTextChannel
Xavier Claessens
xclaesse at kemper.freedesktop.org
Wed May 9 13:10:53 PDT 2012
Module: telepathy-glib
Branch: next
Commit: 9544a1997eed04aecef4ed98ddf776c2759b28b9
URL: http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=9544a1997eed04aecef4ed98ddf776c2759b28b9
Author: Xavier Claessens <xavier.claessens at collabora.co.uk>
Date: Fri Apr 27 14:32:10 2012 +0200
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
---
docs/reference/telepathy-glib-sections.txt | 5 +
telepathy-glib/channel.c | 3 +
telepathy-glib/channel.h | 2 +-
telepathy-glib/text-channel.c | 118 ++++++++++++++++++++++++++++
telepathy-glib/text-channel.h | 6 ++
5 files changed, 133 insertions(+), 1 deletions(-)
diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index 112782b..6bb18b3 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -6574,11 +6574,15 @@ tp_text_channel_ack_all_pending_messages_finish
tp_text_channel_set_chat_state_async
tp_text_channel_set_chat_state_finish
tp_text_channel_supports_message_type
+<SUBSECTION>
TP_TEXT_CHANNEL_FEATURE_SMS
tp_text_channel_is_sms_channel
tp_text_channel_get_sms_flash
tp_text_channel_get_sms_length_async
tp_text_channel_get_sms_length_finish
+<SUBSECTION>
+TP_TEXT_CHANNEL_FEATURE_CHAT_STATES
+tp_text_channel_get_chat_state
<SUBSECTION Standard>
TP_IS_TEXT_CHANNEL
TP_IS_TEXT_CHANNEL_CLASS
@@ -6591,6 +6595,7 @@ TpTextChannelPrivate
<SUBSECTION Private>
tp_text_channel_get_feature_quark_incoming_messages
tp_text_channel_get_feature_quark_sms
+tp_text_channel_get_feature_quark_chat_states
</SECTION>
<SECTION>
diff --git a/telepathy-glib/channel.c b/telepathy-glib/channel.c
index 4aebbc9..1af096a 100644
--- a/telepathy-glib/channel.c
+++ b/telepathy-glib/channel.c
@@ -227,6 +227,7 @@ tp_channel_get_feature_quark_contacts (void)
* tp_proxy_prepare_async() function, and waiting for it to callback.
*
* Since: 0.11.3
+ * Deprecated: Use TP_TEXT_CHANNEL_FEATURE_CHAT_STATES instead.
*/
GQuark
@@ -516,6 +517,7 @@ tp_channel_get_property (GObject *object,
* Returns: the chat state for @contact, or %TP_CHANNEL_CHAT_STATE_INACTIVE
* if their chat state is not known
* Since: 0.11.3
+ * Deprecated: Use tp_text_channel_get_chat_state() instead.
*/
TpChannelChatState
tp_channel_get_chat_state (TpChannel *self,
@@ -1863,6 +1865,7 @@ tp_channel_class_init (TpChannelClass *klass)
* has finished preparing the feature %TP_CHANNEL_FEATURE_CHAT_STATES.
*
* Since: 0.11.3
+ * Deprecated: Use #TpTextChannel::contact-chat-state-changed instead
*/
signals[SIGNAL_CHAT_STATE_CHANGED] = g_signal_new ("chat-state-changed",
G_OBJECT_CLASS_TYPE (klass),
diff --git a/telepathy-glib/channel.h b/telepathy-glib/channel.h
index c0eff34..5662d35 100644
--- a/telepathy-glib/channel.h
+++ b/telepathy-glib/channel.h
@@ -220,7 +220,7 @@ TpContact *tp_channel_group_get_contact_owner (TpChannel *self,
tp_channel_get_feature_quark_chat_states ()
GQuark tp_channel_get_feature_quark_chat_states (void) G_GNUC_CONST;
TpChannelChatState tp_channel_get_chat_state (TpChannel *self,
- TpHandle contact);
+ TpHandle contact) _TP_GNUC_DEPRECATED_FOR (tp_text_channel_get_chat_state);
/* Channel.Interface.Password */
#define TP_CHANNEL_FEATURE_PASSWORD \
diff --git a/telepathy-glib/text-channel.c b/telepathy-glib/text-channel.c
index 387bac1..adf5ca0 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,
diff --git a/telepathy-glib/text-channel.h b/telepathy-glib/text-channel.h
index beb5e71..4f488fc 100644
--- a/telepathy-glib/text-channel.h
+++ b/telepathy-glib/text-channel.h
@@ -121,6 +121,12 @@ gboolean tp_text_channel_ack_all_pending_messages_finish (TpTextChannel *self,
GAsyncResult *result,
GError **error);
+#define TP_TEXT_CHANNEL_FEATURE_CHAT_STATES \
+ tp_text_channel_get_feature_quark_chat_states ()
+GQuark tp_text_channel_get_feature_quark_chat_states (void) G_GNUC_CONST;
+TpChannelChatState tp_text_channel_get_chat_state (TpTextChannel *self,
+ TpContact *contact);
+
void tp_text_channel_set_chat_state_async (TpTextChannel *self,
TpChannelChatState state,
GAsyncReadyCallback callback,
More information about the telepathy-commits
mailing list