diff options
author | Xavier Claessens <xavier.claessens@collabora.co.uk> | 2012-04-30 23:24:01 +0200 |
---|---|---|
committer | Xavier Claessens <xavier.claessens@collabora.co.uk> | 2012-05-09 18:42:26 +0200 |
commit | 956a5f821854494228981c2b7d3095a9a0687427 (patch) | |
tree | a6258694103e90f0bbbb7340325df82c650c8e3c | |
parent | cbfa9d06a8e4cc93b15e4a8b53819638ab09d67c (diff) |
Use TpMessageMixin to implement ChatState
-rw-r--r-- | src/im-channel.c | 134 | ||||
-rw-r--r-- | src/muc-channel.c | 93 |
2 files changed, 59 insertions, 168 deletions
diff --git a/src/im-channel.c b/src/im-channel.c index ba1f45dce..d0e939e51 100644 --- a/src/im-channel.c +++ b/src/im-channel.c @@ -44,7 +44,6 @@ #include "roster.h" #include "util.h" -static void chat_state_iface_init (gpointer, gpointer); static void destroyable_iface_init (gpointer, gpointer); G_DEFINE_TYPE_WITH_CODE (GabbleIMChannel, gabble_im_channel, @@ -54,13 +53,16 @@ G_DEFINE_TYPE_WITH_CODE (GabbleIMChannel, gabble_im_channel, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MESSAGES, tp_message_mixin_messages_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CHAT_STATE, - chat_state_iface_init); + tp_message_mixin_chat_state_iface_init) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DESTROYABLE, destroyable_iface_init)); static void _gabble_im_channel_send_message (GObject *object, TpMessage *message, TpMessageSendingFlags flags); static void gabble_im_channel_close (TpBaseChannel *base_chan); +static gboolean _gabble_im_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error); static const gchar *gabble_im_channel_interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_CHAT_STATE, @@ -84,13 +86,6 @@ struct _GabbleIMChannelPrivate gboolean send_nick; ChatStateSupport chat_states_supported; - /* FALSE unless at least one chat state notification has been sent; <gone/> - * will only be sent when the channel closes if this is TRUE. This prevents - * opening a channel and closing it immediately sending a spurious <gone/> to - * the peer. - */ - gboolean send_gone; - gboolean dispose_has_run; }; @@ -143,8 +138,6 @@ gabble_im_channel_constructed (GObject *obj) else priv->send_nick = TRUE; - priv->chat_states_supported = CHAT_STATES_UNKNOWN; - tp_message_mixin_init (obj, G_STRUCT_OFFSET (GabbleIMChannel, message_mixin), base_conn); @@ -152,6 +145,10 @@ gabble_im_channel_constructed (GObject *obj) G_N_ELEMENTS (types), types, 0, TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_FAILURES, supported_content_types); + + priv->chat_states_supported = CHAT_STATES_UNKNOWN; + tp_message_mixin_implement_send_chat_state (obj, + _gabble_im_channel_send_chat_state); } static void gabble_im_channel_dispose (GObject *object); @@ -238,24 +235,6 @@ chat_states_supported (GabbleIMChannel *self, } static void -im_channel_send_gone (GabbleIMChannel *self) -{ - GabbleIMChannelPrivate *priv = self->priv; - TpBaseChannel *base = (TpBaseChannel *) self; - - if (priv->send_gone) - { - if (chat_states_supported (self, FALSE)) - gabble_message_util_send_chat_state (G_OBJECT (self), - GABBLE_CONNECTION (tp_base_channel_get_connection (base)), - WOCKY_STANZA_SUB_TYPE_CHAT, TP_CHANNEL_CHAT_STATE_GONE, - priv->peer_jid, NULL); - - priv->send_gone = FALSE; - } -} - -static void gabble_im_channel_dispose (GObject *object) { GabbleIMChannel *self = GABBLE_IM_CHANNEL (object); @@ -282,7 +261,7 @@ gabble_im_channel_dispose (GObject *object) } } - im_channel_send_gone (self); + tp_message_mixin_maybe_send_gone (object); if (G_OBJECT_CLASS (gabble_im_channel_parent_class)->dispose) G_OBJECT_CLASS (gabble_im_channel_parent_class)->dispose (object); @@ -340,9 +319,10 @@ _gabble_im_channel_send_message (GObject *object, { GabbleIMChannel *self = GABBLE_IM_CHANNEL (object); TpBaseChannel *base = (TpBaseChannel *) self; + TpBaseConnection *base_conn; GabbleConnection *gabble_conn; GabbleIMChannelPrivate *priv; - gint state = -1; + TpChannelChatState state = -1; WockyStanza *stanza = NULL; gchar *id = NULL; GError *error = NULL; @@ -352,16 +332,18 @@ _gabble_im_channel_send_message (GObject *object, g_assert (GABBLE_IS_IM_CHANNEL (self)); priv = self->priv; + base_conn = tp_base_channel_get_connection (base); + gabble_conn = GABBLE_CONNECTION (base_conn); + if (chat_states_supported (self, TRUE)) { state = TP_CHANNEL_CHAT_STATE_ACTIVE; - priv->send_gone = TRUE; + tp_message_mixin_change_chat_state (object, + base_conn->self_handle, state); } /* We don't support providing successful delivery reports. */ flags = 0; - gabble_conn = - GABBLE_CONNECTION (tp_base_channel_get_connection (base)); stanza = gabble_message_util_build_stanza (message, gabble_conn, 0, state, priv->peer_jid, @@ -555,15 +537,13 @@ _gabble_im_channel_state_receive (GabbleIMChannel *chan, GabbleIMChannelPrivate *priv; TpBaseChannel *base_chan; - g_assert (state < NUM_TP_CHANNEL_CHAT_STATES); g_assert (GABBLE_IS_IM_CHANNEL (chan)); base_chan = (TpBaseChannel *) chan; priv = chan->priv; priv->chat_states_supported = CHAT_STATES_SUPPORTED; - tp_svc_channel_interface_chat_state_emit_chat_state_changed ( - (TpSvcChannelInterfaceChatState *) chan, + tp_message_mixin_change_chat_state ((GObject *) chan, tp_base_channel_get_target_handle (base_chan), state); } @@ -572,7 +552,7 @@ gabble_im_channel_close (TpBaseChannel *base_chan) { GabbleIMChannel *self = GABBLE_IM_CHANNEL (base_chan); - im_channel_send_gone (self); + tp_message_mixin_maybe_send_gone ((GObject *) self); /* The IM factory will resurrect the channel if we have pending * messages. When we're resurrected, we want the initiator @@ -610,76 +590,24 @@ gabble_im_channel_destroy (TpSvcChannelInterfaceDestroyable *iface, tp_svc_channel_interface_destroyable_return_from_destroy (context); } - -/** - * gabble_im_channel_set_chat_state - * - * Implements D-Bus method SetChatState - * on interface org.freedesktop.Telepathy.Channel.Interface.ChatState - */ -static void -gabble_im_channel_set_chat_state (TpSvcChannelInterfaceChatState *iface, - guint state, - DBusGMethodInvocation *context) +static gboolean +_gabble_im_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error) { - GabbleIMChannel *self = GABBLE_IM_CHANNEL (iface); + GabbleIMChannel *self = GABBLE_IM_CHANNEL (object); + GabbleIMChannelPrivate *priv = self->priv; TpBaseChannel *base = (TpBaseChannel *) self; - GabbleIMChannelPrivate *priv; - GError *error = NULL; - - g_assert (GABBLE_IS_IM_CHANNEL (self)); - priv = self->priv; + TpBaseConnection *base_conn = tp_base_channel_get_connection (base); - if (state >= NUM_TP_CHANNEL_CHAT_STATES) - { - g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "invalid state: %u", state); - } - else if (state == TP_CHANNEL_CHAT_STATE_GONE) - { - g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "you may not explicitly set the Gone state"); - } /* Only send anything to the peer if we actually know they support chat - * states. - */ - else if (chat_states_supported (self, FALSE)) - { - TpBaseConnection *base_conn = tp_base_channel_get_connection (base); - - if (gabble_message_util_send_chat_state (G_OBJECT (self), - GABBLE_CONNECTION (base_conn), - WOCKY_STANZA_SUB_TYPE_CHAT, state, priv->peer_jid, &error)) - { - priv->send_gone = TRUE; - - /* Send the ChatStateChanged signal for the local user */ - tp_svc_channel_interface_chat_state_emit_chat_state_changed (iface, - base_conn->self_handle, state); - } - } - - if (error != NULL) - { - DEBUG ("%s", error->message); - dbus_g_method_return_error (context, error); - g_error_free (error); - } - else - { - tp_svc_channel_interface_chat_state_return_from_set_chat_state (context); - } -} + * states. */ + if (!chat_states_supported (self, FALSE)) + return TRUE; -static void -chat_state_iface_init (gpointer g_iface, gpointer iface_data) -{ - TpSvcChannelInterfaceChatStateClass *klass = - (TpSvcChannelInterfaceChatStateClass *) g_iface; -#define IMPLEMENT(x) tp_svc_channel_interface_chat_state_implement_##x (\ - klass, gabble_im_channel_##x) - IMPLEMENT(set_chat_state); -#undef IMPLEMENT + return gabble_message_util_send_chat_state (G_OBJECT (self), + GABBLE_CONNECTION (base_conn), + WOCKY_STANZA_SUB_TYPE_CHAT, state, priv->peer_jid, error); } static void diff --git a/src/muc-channel.c b/src/muc-channel.c index f708e35cf..0a507f916 100644 --- a/src/muc-channel.c +++ b/src/muc-channel.c @@ -59,7 +59,6 @@ #define PROPS_POLL_INTERVAL_HIGH 60 static void password_iface_init (gpointer, gpointer); -static void chat_state_iface_init (gpointer, gpointer); static void subject_iface_init (gpointer, gpointer); #ifdef ENABLE_VOIP static void gabble_muc_channel_start_call_creation (GabbleMucChannel *gmuc, @@ -80,7 +79,7 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMucChannel, gabble_muc_channel, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MESSAGES, tp_message_mixin_messages_iface_init); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CHAT_STATE, - chat_state_iface_init); + tp_message_mixin_chat_state_iface_init) G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CONFERENCE, NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_ROOM, NULL); G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_ROOM_CONFIG, @@ -91,6 +90,9 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMucChannel, gabble_muc_channel, static void gabble_muc_channel_send (GObject *obj, TpMessage *message, TpMessageSendingFlags flags); +static gboolean gabble_muc_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error); static void gabble_muc_channel_close (TpBaseChannel *base); static const gchar *gabble_muc_channel_interfaces[] = { @@ -438,6 +440,8 @@ gabble_muc_channel_constructed (GObject *obj) TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_FAILURES | TP_DELIVERY_REPORTING_SUPPORT_FLAG_RECEIVE_SUCCESSES, supported_content_types); + tp_message_mixin_implement_send_chat_state (obj, + gabble_muc_channel_send_chat_state); tp_group_mixin_add_handle_owner (obj, self_handle, base_conn->self_handle); @@ -2061,6 +2065,8 @@ handle_left (GObject *source, tp_group_mixin_change_members (data, why, NULL, handles, NULL, NULL, actor, reason); + tp_message_mixin_change_chat_state (data, member, + TP_CHANNEL_CHAT_STATE_GONE); if (actor != 0) tp_handle_unref (contact_repo, actor); @@ -2412,7 +2418,7 @@ handle_message (GObject *source, if (from_member && state != WOCKY_MUC_MSG_STATE_NONE) { - gint tp_msg_state; + TpChannelChatState tp_msg_state; switch (state) { case WOCKY_MUC_MSG_STATE_ACTIVE: @@ -2431,8 +2437,7 @@ handle_message (GObject *source, tp_msg_state = TP_CHANNEL_CHAT_STATE_ACTIVE; } - tp_svc_channel_interface_chat_state_emit_chat_state_changed (gmuc, - from, tp_msg_state); + tp_message_mixin_change_chat_state ((GObject *) gmuc, from, tp_msg_state); } if (subject != NULL) @@ -2838,14 +2843,21 @@ gabble_muc_channel_send (GObject *obj, GabbleMucChannel *self = GABBLE_MUC_CHANNEL (obj); TpBaseChannel *base = TP_BASE_CHANNEL (self); GabbleMucChannelPrivate *priv = self->priv; - GabbleConnection *gabble_conn = - GABBLE_CONNECTION (tp_base_channel_get_connection (base)); + TpBaseConnection *base_conn; + GabbleConnection *gabble_conn; _GabbleMUCSendMessageCtx *context = NULL; WockyStanza *stanza = NULL; WockyPorter *porter = NULL; GError *error = NULL; gchar *id = NULL; + base_conn = tp_base_channel_get_connection (base); + gabble_conn = GABBLE_CONNECTION (base_conn); + + tp_message_mixin_change_chat_state (obj, + tp_base_channel_get_self_handle (base), + TP_CHANNEL_CHAT_STATE_ACTIVE); + stanza = gabble_message_util_build_stanza (message, gabble_conn, WOCKY_STANZA_SUB_TYPE_GROUPCHAT, TP_CHANNEL_CHAT_STATE_ACTIVE, priv->jid, FALSE, &id, &error); @@ -3401,55 +3413,18 @@ request_config_form_submit_reply_cb ( g_object_unref (update_result); } -/** - * gabble_muc_channel_set_chat_state - * - * Implements D-Bus method SetChatState - * on interface org.freedesktop.Telepathy.Channel.Interface.ChatState - */ -static void -gabble_muc_channel_set_chat_state (TpSvcChannelInterfaceChatState *iface, - guint state, - DBusGMethodInvocation *context) +static gboolean +gabble_muc_channel_send_chat_state (GObject *object, + TpChannelChatState state, + GError **error) { - GabbleMucChannel *self = GABBLE_MUC_CHANNEL (iface); + GabbleMucChannel *self = GABBLE_MUC_CHANNEL (object); + GabbleMucChannelPrivate *priv = self->priv; TpBaseChannel *base = TP_BASE_CHANNEL (self); - GabbleMucChannelPrivate *priv; - GError *error = NULL; - - g_assert (GABBLE_IS_MUC_CHANNEL (self)); - - priv = self->priv; - - if (state >= NUM_TP_CHANNEL_CHAT_STATES) - { - DEBUG ("invalid state %u", state); - - g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "invalid state: %u", state); - } - if (state == TP_CHANNEL_CHAT_STATE_GONE) - { - /* We cannot explicitly set the Gone state */ - DEBUG ("you may not explicitly set the Gone state"); - - g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, - "you may not explicitly set the Gone state"); - } - - if (error != NULL || - !gabble_message_util_send_chat_state (G_OBJECT (self), - GABBLE_CONNECTION (tp_base_channel_get_connection (base)), - WOCKY_STANZA_SUB_TYPE_GROUPCHAT, state, priv->jid, &error)) - { - dbus_g_method_return_error (context, error); - g_error_free (error); - - return; - } - - tp_svc_channel_interface_chat_state_return_from_set_chat_state (context); + return gabble_message_util_send_chat_state (G_OBJECT (self), + GABBLE_CONNECTION (tp_base_channel_get_connection (base)), + WOCKY_STANZA_SUB_TYPE_GROUPCHAT, state, priv->jid, error); } void @@ -3843,18 +3818,6 @@ password_iface_init (gpointer g_iface, gpointer iface_data) } static void -chat_state_iface_init (gpointer g_iface, gpointer iface_data) -{ - TpSvcChannelInterfaceChatStateClass *klass = - (TpSvcChannelInterfaceChatStateClass *) g_iface; - -#define IMPLEMENT(x) tp_svc_channel_interface_chat_state_implement_##x (\ - klass, gabble_muc_channel_##x) - IMPLEMENT(set_chat_state); -#undef IMPLEMENT -} - -static void subject_iface_init (gpointer g_iface, gpointer iface_data) { TpSvcChannelInterfaceSubjectClass *klass = |