summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.co.uk>2012-04-30 23:24:01 +0200
committerXavier Claessens <xavier.claessens@collabora.co.uk>2012-05-09 18:42:26 +0200
commit956a5f821854494228981c2b7d3095a9a0687427 (patch)
treea6258694103e90f0bbbb7340325df82c650c8e3c
parentcbfa9d06a8e4cc93b15e4a8b53819638ab09d67c (diff)
Use TpMessageMixin to implement ChatState
-rw-r--r--src/im-channel.c134
-rw-r--r--src/muc-channel.c93
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 =