diff options
Diffstat (limited to 'src/salut-muc-channel.c')
-rw-r--r-- | src/salut-muc-channel.c | 830 |
1 files changed, 308 insertions, 522 deletions
diff --git a/src/salut-muc-channel.c b/src/salut-muc-channel.c index c539d1ff..5bf783f9 100644 --- a/src/salut-muc-channel.c +++ b/src/salut-muc-channel.c @@ -28,33 +28,36 @@ #include "salut-muc-channel.h" #include "salut-muc-channel-signals-marshal.h" -#include "salut-muc-channel-glue.h" #include <gibber/gibber-transport.h> +#include <telepathy-glib/channel-iface.h> +#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/dbus.h> +#include <telepathy-glib/errors.h> +#include <telepathy-glib/util.h> + #include "salut-muc-transport-iface.h" #include "salut-muc-connection.h" #include "salut-connection.h" #include "salut-im-manager.h" -#include "telepathy-interfaces.h" -#include "telepathy-helpers.h" -#include "telepathy-errors.h" -#include "tp-channel-iface.h" #include "namespaces.h" +#include "text-helper.h" -G_DEFINE_TYPE_WITH_CODE(SalutMucChannel, salut_muc_channel, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL)); - -/* signal enum */ -enum -{ - CLOSED, - LAST_SIGNAL -}; +static void +channel_iface_init(gpointer g_iface, gpointer iface_data); +static void +text_iface_init(gpointer g_iface, gpointer iface_data); -static guint signals[LAST_SIGNAL] = {0}; +G_DEFINE_TYPE_WITH_CODE(SalutMucChannel, salut_muc_channel, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL, channel_iface_init); + G_IMPLEMENT_INTERFACE(TP_TYPE_CHANNEL_IFACE, NULL); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP, + tp_group_mixin_iface_init); + G_IMPLEMENT_INTERFACE(TP_TYPE_SVC_CHANNEL_TYPE_TEXT, text_iface_init); +) /* properties */ enum @@ -77,7 +80,7 @@ struct _SalutMucChannelPrivate { gboolean dispose_has_run; gchar *object_path; - Handle handle; + TpHandle handle; SalutConnection *connection; SalutImManager *im_manager; SalutMucConnection *muc_connection; @@ -90,10 +93,11 @@ struct _SalutMucChannelPrivate /* Callback functions */ static void salut_muc_channel_send_presence(SalutMucChannel *self, gboolean joining); -static gboolean salut_muc_channel_send_stanza(GObject *object, guint type, - const gchar *text, - GibberXmppStanza *stanza, - GError **error); +static gboolean salut_muc_channel_send_stanza(SalutMucChannel *self, + guint type, + const gchar *text, + GibberXmppStanza *stanza, + GError **error); static void salut_muc_channel_received_stanza(GibberXmppConnection *conn, GibberXmppStanza *stanza, gpointer user_data); @@ -154,6 +158,7 @@ salut_muc_channel_set_property (GObject *object, { SalutMucChannel *chan = SALUT_MUC_CHANNEL (object); SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (chan); + const gchar *tmp; switch (property_id) { case PROP_OBJECT_PATH: @@ -177,6 +182,16 @@ salut_muc_channel_set_property (GObject *object, case PROP_MUCCONNECTION: priv->muc_connection = g_value_get_object (value); break; + case PROP_HANDLE_TYPE: + g_assert(g_value_get_uint(value) == 0 + || g_value_get_uint(value) == TP_HANDLE_TYPE_ROOM); + break; + case PROP_CHANNEL_TYPE: + tmp = g_value_get_string(value); + g_assert(tmp == NULL + || !tp_strdiff(g_value_get_string(value), + TP_IFACE_CHANNEL_TYPE_TEXT)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -190,8 +205,10 @@ salut_muc_channel_constructor (GType type, guint n_props, GObjectConstructParam *props) { GObject *obj; DBusGConnection *bus; - gboolean valid; SalutMucChannelPrivate *priv; + TpBaseConnection *base_conn; + TpHandleRepoIface *handle_repo; + TpHandleRepoIface *contact_repo; /* Parent constructor chain */ obj = G_OBJECT_CLASS(salut_muc_channel_parent_class)-> @@ -200,15 +217,20 @@ salut_muc_channel_constructor (GType type, guint n_props, priv = SALUT_MUC_CHANNEL_GET_PRIVATE (SALUT_MUC_CHANNEL (obj)); /* Ref our handle */ - valid = handle_ref(priv->connection->handle_repo, TP_HANDLE_TYPE_ROOM, - priv->handle); - g_assert(valid); - + base_conn = TP_BASE_CONNECTION(priv->connection); + + handle_repo = tp_base_connection_get_handles(base_conn, + TP_HANDLE_TYPE_ROOM); + + tp_handle_ref(handle_repo, priv->handle); + /* Text mixin initialisation */ - text_mixin_init(obj, G_STRUCT_OFFSET(SalutMucChannel, text), - priv->connection->handle_repo); + contact_repo = tp_base_connection_get_handles(base_conn, + TP_HANDLE_TYPE_CONTACT); + tp_text_mixin_init(obj, G_STRUCT_OFFSET(SalutMucChannel, text), + contact_repo); - text_mixin_set_message_types(obj, + tp_text_mixin_set_message_types(obj, TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION, G_MAXUINT); @@ -217,11 +239,12 @@ salut_muc_channel_constructor (GType type, guint n_props, bus = tp_get_bus (); dbus_g_connection_register_g_object(bus, priv->object_path, obj); - group_mixin_init(obj, G_STRUCT_OFFSET(SalutMucChannel, group), - priv->connection->handle_repo, - priv->connection->self_handle); - group_mixin_change_flags(obj, - TP_CHANNEL_GROUP_FLAG_CAN_ADD|TP_CHANNEL_GROUP_FLAG_MESSAGE_ADD, 0); + tp_group_mixin_init(TP_SVC_CHANNEL_INTERFACE_GROUP(obj), + G_STRUCT_OFFSET(SalutMucChannel, group), + contact_repo, base_conn->self_handle); + + tp_group_mixin_change_flags(TP_SVC_CHANNEL_INTERFACE_GROUP(obj), + TP_CHANNEL_GROUP_FLAG_CAN_ADD|TP_CHANNEL_GROUP_FLAG_MESSAGE_ADD, 0); return obj; } @@ -247,12 +270,17 @@ invitation_append_parameter(gpointer key, gpointer value, gpointer data) { } static GibberXmppStanza * -create_invitation(SalutMucChannel *self, Handle handle, const gchar *message) { +create_invitation(SalutMucChannel *self, TpHandle handle, const gchar *message) { SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (self); + TpBaseConnection *base_connection = TP_BASE_CONNECTION(priv->connection); + TpHandleRepoIface *contact_repo = + tp_base_connection_get_handles(base_connection, TP_HANDLE_TYPE_CONTACT); + TpHandleRepoIface *room_repo = + tp_base_connection_get_handles(base_connection, TP_HANDLE_TYPE_ROOM); GibberXmppStanza *msg; GibberXmppNode *x_node, *invite_node; - const gchar *name = handle_inspect(priv->connection->handle_repo, - TP_HANDLE_TYPE_CONTACT, handle); + + const gchar *name = tp_handle_inspect(contact_repo, handle); msg = gibber_xmpp_stanza_new("message"); @@ -272,8 +300,7 @@ create_invitation(SalutMucChannel *self, Handle handle, const gchar *message) { } gibber_xmpp_node_add_child_with_content(invite_node, "roomname", - handle_inspect(priv->connection->handle_repo, - TP_HANDLE_TYPE_ROOM, priv->handle)); + tp_handle_inspect(room_repo, priv->handle)); g_hash_table_foreach( (GHashTable *)salut_muc_connection_get_parameters(priv->muc_connection), invitation_append_parameter, invite_node); @@ -282,41 +309,41 @@ create_invitation(SalutMucChannel *self, Handle handle, const gchar *message) { } static gboolean -muc_channel_add_member(GObject *obj, Handle handle, +muc_channel_add_member(TpSvcChannelInterfaceGroup *iface, TpHandle handle, const gchar *message, GError **error) { - SalutMucChannel *self = SALUT_MUC_CHANNEL(obj); + SalutMucChannel *self = SALUT_MUC_CHANNEL(iface); SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (self); + TpBaseConnection *base_connection = TP_BASE_CONNECTION(priv->connection); SalutImChannel *im_channel; GibberXmppStanza *stanza; - if (handle == priv->connection->self_handle) { - GIntSet *empty; - GIntSet *add; + if (handle == base_connection->self_handle) { + TpIntSet *empty; + TpIntSet *add; gboolean ret = TRUE; - empty = g_intset_new(); - add = g_intset_new(); - g_intset_add(add, handle); + empty = tp_intset_new(); + add = tp_intset_new(); + tp_intset_add(add, handle); /* Add to members */ if (salut_muc_channel_connect(self, NULL)) { - group_mixin_change_members(G_OBJECT(self), message, - add, empty, empty, empty, - priv->connection->self_handle, + tp_group_mixin_change_members(TP_SVC_CHANNEL_INTERFACE_GROUP(self), + message, add, empty, empty, empty, base_connection->self_handle, TP_CHANNEL_GROUP_CHANGE_REASON_INVITED); } else { g_set_error(error, - TELEPATHY_ERRORS, NetworkError, + TP_ERRORS, TP_ERROR_NETWORK_ERROR, "Failed to connect to the group"); ret = FALSE; } - g_intset_destroy(empty); - g_intset_destroy(add); + tp_intset_destroy(empty); + tp_intset_destroy(add); return ret; } im_channel = salut_im_manager_get_channel_for_handle(priv->im_manager, handle); if (im_channel == NULL) { - *error = g_error_new(TELEPATHY_ERRORS, NotAvailable, + *error = g_error_new(TP_ERRORS, TP_ERROR_NOT_AVAILABLE, "Couldn't contact the contact"); return FALSE; } @@ -396,24 +423,12 @@ salut_muc_channel_class_init (SalutMucChannelClass *salut_muc_channel_class) { g_object_class_install_property (object_class, PROP_IM_MANAGER, param_spec); - signals[CLOSED] = - g_signal_new ("closed", - G_OBJECT_CLASS_TYPE (salut_muc_channel_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - text_mixin_class_init(object_class, - G_STRUCT_OFFSET(SalutMucChannelClass, text_class), - salut_muc_channel_send_stanza); + tp_text_mixin_class_init(object_class, + G_STRUCT_OFFSET(SalutMucChannelClass, text_class)); - group_mixin_class_init(object_class, + tp_group_mixin_class_init((TpSvcChannelInterfaceGroupClass *)object_class, G_STRUCT_OFFSET(SalutMucChannelClass, group_class), muc_channel_add_member, NULL); - - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (salut_muc_channel_class), &dbus_glib_salut_muc_channel_object_info); } void @@ -436,10 +451,7 @@ salut_muc_channel_dispose (GObject *object) priv->muc_connection = NULL; } - - /* release any references held by the object here */ - if (G_OBJECT_CLASS (salut_muc_channel_parent_class)->dispose) G_OBJECT_CLASS (salut_muc_channel_parent_class)->dispose (object); } @@ -453,466 +465,73 @@ salut_muc_channel_finalize (GObject *object) /* free any data held directly by the object here */ g_free(priv->object_path); - text_mixin_finalize(object); + tp_text_mixin_finalize(object); + tp_group_mixin_finalize(TP_SVC_CHANNEL_INTERFACE_GROUP(object)); G_OBJECT_CLASS (salut_muc_channel_parent_class)->finalize (object); } void -salut_muc_channel_invited(SalutMucChannel *self, Handle invitor, +salut_muc_channel_invited(SalutMucChannel *self, TpHandle invitor, const gchar *stanza) { SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(self); + TpBaseConnection *base_connection = TP_BASE_CONNECTION(priv->connection); + TpHandleRepoIface *contact_repo = + tp_base_connection_get_handles(base_connection, TP_HANDLE_TYPE_CONTACT); + TpHandleRepoIface *room_repo = + tp_base_connection_get_handles(base_connection, TP_HANDLE_TYPE_ROOM); /* Got invited to this muc channel */ DEBUG("Got an invitation to %s from %s", - handle_inspect(priv->connection->handle_repo, TP_HANDLE_TYPE_ROOM, - priv->handle), - handle_inspect(priv->connection->handle_repo, TP_HANDLE_TYPE_CONTACT, - invitor) + tp_handle_inspect(room_repo, priv->handle), + tp_handle_inspect(contact_repo, invitor) ); + /* If we are already a member, no further actions are needed */ - if (handle_set_is_member(self->group.members, - priv->connection->self_handle)) { + if (tp_handle_set_is_member(self->group.members, + base_connection->self_handle)) { return; } - if (invitor == priv->connection->self_handle) { + if (invitor == base_connection->self_handle) { /* Invited ourselves, go straight to members */ GError *error = NULL; - GArray *members = g_array_sized_new (FALSE, FALSE, sizeof (Handle), 1); - g_array_append_val(members, priv->connection->self_handle); - group_mixin_add_members(G_OBJECT(self), members, "", &error); + GArray *members = g_array_sized_new (FALSE, FALSE, sizeof(TpHandle), 1); + g_array_append_val(members, base_connection->self_handle); + tp_group_mixin_add_members(TP_SVC_CHANNEL_INTERFACE_GROUP(self), + members, "", &error); g_array_free(members, TRUE); } else { - GIntSet *empty = g_intset_new(); - GIntSet *local_pending = g_intset_new(); - g_intset_add(local_pending, priv->connection->self_handle); - group_mixin_change_members(G_OBJECT(self), stanza, - empty, empty, - local_pending, empty, - invitor, - TP_CHANNEL_GROUP_CHANGE_REASON_INVITED); - g_intset_destroy(local_pending); - g_intset_destroy(empty); - } -} - -/** - * salut_muc_channel_acknowledge_pending_messages - * - * Implements D-Bus method AcknowledgePendingMessages - * on interface org.freedesktop.Telepathy.Channel.Type.Text - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_acknowledge_pending_messages (SalutMucChannel *self, - const GArray *ids, - GError **error) { - return text_mixin_acknowledge_pending_messages(G_OBJECT(self), ids, error); -} - - -/** - * salut_muc_channel_add_members - * - * Implements D-Bus method AddMembers - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_add_members (SalutMucChannel *self, - const GArray *contacts, - const gchar *stanza, - GError **error) { - return group_mixin_add_members (G_OBJECT (self), contacts, stanza, - error); -} - - -/** - * salut_muc_channel_close - * - * Implements D-Bus method Close - * on interface org.freedesktop.Telepathy.Channel - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_close (SalutMucChannel *self, - GError **error) { - SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (self); - - - if (priv->presence_timeout_id != 0) { - g_source_remove(priv->presence_timeout_id); - priv->presence_timeout_id = 0; + TpIntSet *empty = tp_intset_new(); + TpIntSet *local_pending = tp_intset_new(); + tp_intset_add(local_pending, base_connection->self_handle); + tp_group_mixin_change_members(TP_SVC_CHANNEL_INTERFACE_GROUP(self), stanza, + empty, empty, + local_pending, empty, + invitor, + TP_CHANNEL_GROUP_CHANGE_REASON_INVITED); + tp_intset_destroy(local_pending); + tp_intset_destroy(empty); } - - salut_muc_channel_send_presence(self, FALSE); - gibber_transport_disconnect( - GIBBER_XMPP_CONNECTION(priv->muc_connection)->transport); - - return TRUE; } -/** - * salut_muc_channel_get_all_members - * - * Implements D-Bus method GetAllMembers - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_all_members (SalutMucChannel *self, - GArray **ret, - GArray **ret1, - GArray **ret2, - GError **error) -{ - return group_mixin_get_all_members (G_OBJECT (self), ret, ret1, ret2, error); -} - - -/** - * salut_muc_channel_get_channel_type - * - * Implements D-Bus method GetChannelType - * on interface org.freedesktop.Telepathy.Channel - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_channel_type (SalutMucChannel *self, - gchar **ret, - GError **error) { - *ret = g_strdup (TP_IFACE_CHANNEL_TYPE_TEXT); - return TRUE; -} - - -/** - * salut_muc_channel_get_group_flags - * - * Implements D-Bus method GetGroupFlags - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_group_flags (SalutMucChannel *self, - guint *ret, - GError **error) -{ - return group_mixin_get_group_flags (G_OBJECT (self), ret, error); -} - - -/** - * salut_muc_channel_get_handle - * - * Implements D-Bus method GetHandle - * on interface org.freedesktop.Telepathy.Channel - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_handle (SalutMucChannel *self, - guint *ret, - guint *ret1, - GError **error) -{ - SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (self); - *ret = TP_HANDLE_TYPE_ROOM; - *ret1 = priv->handle; - - return TRUE; -} - - -/** - * salut_muc_channel_get_handle_owners - * - * Implements D-Bus method GetHandleOwners - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_handle_owners (SalutMucChannel *self, - const GArray *handles, - GArray **ret, - GError **error) -{ - *ret = g_array_sized_new(FALSE, FALSE, - sizeof(Handle), handles->len); - *ret = g_array_insert_vals(*ret, 0, handles->data, handles->len); - return TRUE; -} - - -/** - * salut_muc_channel_get_interfaces - * - * Implements D-Bus method GetInterfaces - * on interface org.freedesktop.Telepathy.Channel - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_interfaces (SalutMucChannel *self, - gchar ***ret, - GError **error) { - const char *interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_GROUP, - NULL }; - - *ret = g_strdupv ((gchar **) interfaces); - return TRUE; -} - - -/** - * salut_muc_channel_get_local_pending_members - * - * Implements D-Bus method GetLocalPendingMembers - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_local_pending_members (SalutMucChannel *self, - GArray **ret, - GError **error) { - return group_mixin_get_local_pending_members (G_OBJECT (self), ret, error); -} - - -/** - * salut_muc_channel_get_local_pending_members_with_info - * - * Implements D-Bus method GetLocalPendingMembersWithInfo - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_local_pending_members_with_info ( - SalutMucChannel *self, - GPtrArray **ret, - GError **error) -{ - return group_mixin_get_local_pending_members_with_info(G_OBJECT (self), ret, - error); -} - - -/** - * salut_muc_channel_get_members - * - * Implements D-Bus method GetMembers - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_members (SalutMucChannel *self, - GArray **ret, - GError **error) -{ - return group_mixin_get_members (G_OBJECT (self), ret, error); -} - - -/** - * salut_muc_channel_get_message_types - * - * Implements D-Bus method GetMessageTypes - * on interface org.freedesktop.Telepathy.Channel.Type.Text - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_message_types (SalutMucChannel *self, - GArray **ret, - GError **error) { - return text_mixin_get_message_types(G_OBJECT(self), ret, error); -} - - -/** - * salut_muc_channel_get_remote_pending_members - * - * Implements D-Bus method GetRemotePendingMembers - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_remote_pending_members (SalutMucChannel *self, - GArray **ret, - GError **error) { - return group_mixin_get_remote_pending_members (G_OBJECT (self), ret, error); -} - - -/** - * salut_muc_channel_get_self_handle - * - * Implements D-Bus method GetSelfHandle - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_get_self_handle (SalutMucChannel *self, - guint *ret, - GError **error) { - return group_mixin_get_self_handle (G_OBJECT (self), ret, error); -} - - -/** - * salut_muc_channel_list_pending_messages - * - * Implements D-Bus method ListPendingMessages - * on interface org.freedesktop.Telepathy.Channel.Type.Text - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_list_pending_messages (SalutMucChannel *self, - gboolean clear, - GPtrArray **ret, - GError **error) { - return text_mixin_list_pending_messages(G_OBJECT(self), clear, ret, error); -} - - -/** - * salut_muc_channel_remove_members - * - * Implements D-Bus method RemoveMembers - * on interface org.freedesktop.Telepathy.Channel.Interface.Group - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_remove_members (SalutMucChannel *self, - const GArray *contacts, - const gchar *stanza, - GError **error) +/* Private functions */ +static gboolean +salut_muc_channel_send_stanza(SalutMucChannel *self, guint type, + const gchar *text, + GibberXmppStanza *stanza, + GError **error) { - return group_mixin_remove_members(G_OBJECT (self), contacts, stanza, error); -} - - -/** - * salut_muc_channel_send - * - * Implements D-Bus method Send - * on interface org.freedesktop.Telepathy.Channel.Type.Text - * - * @error: Used to return a pointer to a GError detailing any error - * that occurred, D-Bus will throw the error only if this - * function returns FALSE. - * - * Returns: TRUE if successful, FALSE if an error was thrown. - */ -gboolean -salut_muc_channel_send (SalutMucChannel *self, - guint type, const gchar *text, - GError **error) { SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(self); - return text_mixin_send(G_OBJECT(self), type, - priv->connection->name, - priv->muc_name, text, error); -} - -/* Private functions */ -static gboolean salut_muc_channel_send_stanza(GObject *object, guint type, - const gchar *text, - GibberXmppStanza *stanza, - GError **error) { - SalutMucChannel *self = SALUT_MUC_CHANNEL(object); - SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(object); if (!gibber_xmpp_connection_send(GIBBER_XMPP_CONNECTION(priv->muc_connection), stanza, error)) { - text_mixin_emit_send_error(G_OBJECT(self), CHANNEL_TEXT_SEND_ERROR_UNKNOWN, - time(NULL), type, text); + tp_svc_channel_type_text_emit_send_error(self, + TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN, time(NULL), type, text); return FALSE; } - text_mixin_emit_sent(G_OBJECT(self), time(NULL), type, text); + + tp_svc_channel_type_text_emit_sent(self, time(NULL), type, text); return TRUE; } @@ -948,13 +567,13 @@ salut_muc_channel_presence_timeout(gpointer data) { static void salut_muc_channel_change_members(SalutMucChannel *self, - Handle from_handle, + TpHandle from_handle, gboolean joining) { SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(self); gboolean is_member; - GIntSet *empty, *changes; + TpIntSet *empty, *changes; - is_member = handle_set_is_member(self->group.members, from_handle); + is_member = tp_handle_set_is_member(self->group.members, from_handle); if (is_member == joining) { return; } @@ -966,18 +585,18 @@ salut_muc_channel_change_members(SalutMucChannel *self, salut_muc_channel_presence_timeout, self); } - empty = g_intset_new(); - changes = g_intset_new(); - g_intset_add(changes, from_handle); - group_mixin_change_members(G_OBJECT(self), + empty = tp_intset_new(); + changes = tp_intset_new(); + tp_intset_add(changes, from_handle); + tp_group_mixin_change_members(TP_SVC_CHANNEL_INTERFACE_GROUP(self), "", joining ? changes : empty, joining ? empty : changes, empty, empty, from_handle, TP_CHANNEL_GROUP_CHANGE_REASON_NONE); - g_intset_destroy(changes); - g_intset_destroy(empty); + tp_intset_destroy(changes); + tp_intset_destroy(empty); } static void @@ -986,9 +605,12 @@ salut_muc_channel_received_stanza(GibberXmppConnection *conn, gpointer user_data) { SalutMucChannel *self = SALUT_MUC_CHANNEL(user_data); SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(self); + TpBaseConnection *base_connection = TP_BASE_CONNECTION(priv->connection); + TpHandleRepoIface *contact_repo = + tp_base_connection_get_handles(base_connection, TP_HANDLE_TYPE_CONTACT); const gchar *from, *to, *body, *body_offset; TpChannelTextMessageType msgtype; - Handle from_handle; + TpHandle from_handle; to = gibber_xmpp_node_get_attribute(stanza->node, "to"); if (strcmp(to, priv->muc_name)) { @@ -1000,8 +622,8 @@ salut_muc_channel_received_stanza(GibberXmppConnection *conn, salut_muc_channel_received_presence(self, stanza); } - if (!text_mixin_parse_incoming_message(stanza, &from, &msgtype, - &body, &body_offset)) { + if (!text_helper_parse_incoming_message(stanza, &from, &msgtype, + &body, &body_offset)) { DEBUG("Couldn't parse stanza"); return; } @@ -1011,7 +633,7 @@ salut_muc_channel_received_stanza(GibberXmppConnection *conn, return; } - from_handle = handle_for_contact(priv->connection->handle_repo, from); + from_handle = tp_handle_lookup(contact_repo, from, NULL, NULL); if (from_handle == 0) { /* FIXME, unknown contact.. Need some way to handle this safely, * just adding the contact is somewhat scary */ @@ -1022,17 +644,20 @@ salut_muc_channel_received_stanza(GibberXmppConnection *conn, salut_muc_channel_change_members(self, from_handle, TRUE); /* FIXME validate the from and the to */ /* FIXME fix the text-mixin to actually get a to */ - text_mixin_receive(G_OBJECT(self), msgtype, from_handle, - time(NULL), body_offset); + tp_text_mixin_receive(G_OBJECT(self), msgtype, from_handle, + time(NULL), body_offset); } static void salut_muc_channel_received_presence(SalutMucChannel *channel, GibberXmppStanza *stanza) { SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(channel); + TpBaseConnection *base_connection = TP_BASE_CONNECTION(priv->connection); + TpHandleRepoIface *contact_repo = + tp_base_connection_get_handles(base_connection, TP_HANDLE_TYPE_CONTACT); gboolean joining = TRUE; const gchar *type; const gchar *from; - Handle from_handle; + TpHandle from_handle; type = gibber_xmpp_node_get_attribute(stanza->node, "type"); if (type != NULL && strcmp(type, "unavailable") == 0) { @@ -1047,7 +672,7 @@ static void salut_muc_channel_received_presence(SalutMucChannel *channel, DEBUG("Presence from: %s (joining: %d)", from, joining); - from_handle = handle_for_contact(priv->connection->handle_repo, from); + from_handle = tp_handle_lookup(contact_repo, from, NULL, NULL); if (from_handle == 0) { DEBUG("Unknown contact"); return; @@ -1058,8 +683,8 @@ static void salut_muc_channel_received_presence(SalutMucChannel *channel, static gboolean salut_muc_channel_dummy_timeout(gpointer data) { - SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(data); - priv->presence_timeout_id = 0; + SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(data); + priv->presence_timeout_id = 0; return FALSE; } @@ -1098,6 +723,7 @@ salut_muc_channel_connected(GibberTransport *transport, priv->presence_timeout_id = g_timeout_add(4000, salut_muc_channel_dummy_timeout, self); + g_assert(priv->presence_timeout_id != 0); salut_muc_channel_send_presence(self, TRUE); } @@ -1105,5 +731,165 @@ static void salut_muc_channel_disconnected(GibberTransport *transport, gpointer user_data) { SalutMucChannel *self = SALUT_MUC_CHANNEL(user_data); - g_signal_emit(self, signals[CLOSED], 0); + tp_svc_channel_emit_closed(self); +} + +/* channel interfaces */ +/** + * salut_muc_channel_get_interfaces + * + * Implements D-Bus method GetInterfaces + * on interface org.freedesktop.Telepathy.Channel + * + * @error: Used to return a pointer to a GError detailing any error + * that occurred, D-Bus will throw the error only if this + * function returns FALSE. + * + * Returns: TRUE if successful, FALSE if an error was thrown. + */ +static void +salut_muc_channel_get_interfaces (TpSvcChannel *iface, + DBusGMethodInvocation *context) { + const char *interfaces[] = { TP_IFACE_CHANNEL_INTERFACE_GROUP, NULL }; + + tp_svc_channel_return_from_get_interfaces (context, interfaces); +} + + +/** + * salut_muc_channel_get_handle + * + * Implements D-Bus method GetHandle + * on interface org.freedesktop.Telepathy.Channel + * + * @error: Used to return a pointer to a GError detailing any error + * that occurred, D-Bus will throw the error only if this + * function returns FALSE. + * + * Returns: TRUE if successful, FALSE if an error was thrown. + */ +static void +salut_muc_channel_get_handle (TpSvcChannel *iface, + DBusGMethodInvocation *context) +{ + SalutMucChannel *self = SALUT_MUC_CHANNEL(iface); + SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (self); + + tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_CONTACT, + priv->handle); } +/** + * salut_muc_channel_get_channel_type + * + * Implements D-Bus method GetChannelType + * on interface org.freedesktop.Telepathy.Channel + * + * @error: Used to return a pointer to a GError detailing any error + * that occurred, D-Bus will throw the error only if this + * function returns FALSE. + * + * Returns: TRUE if successful, FALSE if an error was thrown. + */ +static void +salut_muc_channel_get_channel_type (TpSvcChannel *iface, + DBusGMethodInvocation *context) { + tp_svc_channel_return_from_get_channel_type(context, + TP_IFACE_CHANNEL_TYPE_TEXT); +} + +/** + * salut_muc_channel_close + * + * Implements D-Bus method Close + * on interface org.freedesktop.Telepathy.Channel + * + * @error: Used to return a pointer to a GError detailing any error + * that occurred, D-Bus will throw the error only if this + * function returns FALSE. + * + * Returns: TRUE if successful, FALSE if an error was thrown. + */ +static void +salut_muc_channel_close (TpSvcChannel *iface, DBusGMethodInvocation *context) { + SalutMucChannel *self = SALUT_MUC_CHANNEL(iface); + SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE (self); + + DEBUG("Disposing muc channel: %d", priv->presence_timeout_id); + + if (priv->presence_timeout_id != 0) { + g_source_remove(priv->presence_timeout_id); + priv->presence_timeout_id = 0; + } + + salut_muc_channel_send_presence(self, FALSE); + gibber_transport_disconnect( + GIBBER_XMPP_CONNECTION(priv->muc_connection)->transport); + + tp_svc_channel_return_from_close(context); +} + +static void +channel_iface_init(gpointer g_iface, gpointer iface_data) { + TpSvcChannelClass *klass = (TpSvcChannelClass *)g_iface; + +#define IMPLEMENT(x) tp_svc_channel_implement_##x (\ + klass, salut_muc_channel_##x) + IMPLEMENT(close); + IMPLEMENT(get_channel_type); + IMPLEMENT(get_handle); + IMPLEMENT(get_interfaces); +#undef IMPLEMENT +} + + +/** + * salut_muc_channel_send + * + * Implements D-Bus method Send + * on interface org.freedesktop.Telepathy.Channel.Type.Text + * + * @error: Used to return a pointer to a GError detailing any error + * that occurred, D-Bus will throw the error only if this + * function returns FALSE. + * + * Returns: TRUE if successful, FALSE if an error was thrown. + */ +static void +salut_muc_channel_send (TpSvcChannelTypeText *channel, + guint type, const gchar * text, + DBusGMethodInvocation *context) { + SalutMucChannel *self = SALUT_MUC_CHANNEL(channel); + SalutMucChannelPrivate *priv = SALUT_MUC_CHANNEL_GET_PRIVATE(self); + GError *error = NULL; + + GibberXmppStanza *stanza = + text_helper_create_message(priv->connection->name, + priv->muc_name, type, text, &error); + + if (stanza == NULL) { + dbus_g_method_return_error(context, error); + g_error_free(error); + return; + } + + if (!salut_muc_channel_send_stanza(self, type, text, stanza, &error)) { + g_object_unref(G_OBJECT(stanza)); + dbus_g_method_return_error(context, error); + g_error_free(error); + } + + g_object_unref(G_OBJECT(stanza)); + tp_svc_channel_type_text_return_from_send(context); +} + +static void +text_iface_init(gpointer g_iface, gpointer iface_data) { + TpSvcChannelTypeTextClass *klass = (TpSvcChannelTypeTextClass *)g_iface; + + tp_text_mixin_iface_init (g_iface, iface_data); +#define IMPLEMENT(x) tp_svc_channel_type_text_implement_##x (\ + klass, salut_muc_channel_##x) + IMPLEMENT(send); +#undef IMPLEMENT +} + |