diff options
author | Xavier Claessens <xavier.claessens@collabora.co.uk> | 2012-04-27 14:32:10 +0200 |
---|---|---|
committer | Xavier Claessens <xavier.claessens@collabora.co.uk> | 2012-05-09 18:10:41 +0200 |
commit | 9544a1997eed04aecef4ed98ddf776c2759b28b9 (patch) | |
tree | 69e4878adb308161e5f774991e8680d006d25ec4 /telepathy-glib/text-channel.c | |
parent | 76205ffed60d37618e04c479299c09ee497dcd15 (diff) | |
download | telepathy-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.c | 118 |
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, |