Beispiel #1
0
static void
dispatch_cb (EmpathyDispatcher *dispatcher,
	     EmpathyDispatchOperation *operation,
	     gpointer           user_data)
{
	GQuark channel_type;

	channel_type = empathy_dispatch_operation_get_channel_type_id (operation);

	if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT) {
		EmpathyTpChat *tp_chat;
		EmpathyChat   *chat = NULL;
		const gchar   *id;

		tp_chat = EMPATHY_TP_CHAT (
			empathy_dispatch_operation_get_channel_wrapper (operation));

		id = empathy_tp_chat_get_id (tp_chat);
		if (!id) {
			EmpathyContact *contact;

			contact = empathy_tp_chat_get_remote_contact (tp_chat);
			if (contact) {
				id = empathy_contact_get_id (contact);
			}
		}

		if (id) {
			McAccount *account;

			account = empathy_tp_chat_get_account (tp_chat);
			chat = empathy_chat_window_find_chat (account, id);
		}

		if (chat) {
			empathy_chat_set_tp_chat (chat, tp_chat);
		} else {
			chat = empathy_chat_new (tp_chat);
		}

		empathy_chat_window_present_chat (chat);

		empathy_dispatch_operation_claim (operation);
	} else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) {
		EmpathyCallFactory *factory;

		factory = empathy_call_factory_get ();
		empathy_call_factory_claim_channel (factory, operation);
	} else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER) {
		EmpathyFTManager *ft_manager;
		EmpathyTpFile    *tp_file;

		ft_manager = empathy_ft_manager_dup_singleton ();
		tp_file = EMPATHY_TP_FILE (
			empathy_dispatch_operation_get_channel_wrapper (operation));
		empathy_ft_manager_add_tp_file (ft_manager, tp_file);
		empathy_dispatch_operation_claim (operation);
	}
}
static void
tp_file_state_changed_cb (TpChannel *proxy,
    guint state,
    guint reason,
    gpointer user_data,
    GObject *weak_object)
{
  EmpathyTpFile *self = (EmpathyTpFile *) weak_object;
  GError *error = NULL;

  if (state == self->priv->state)
    return;

  DEBUG ("File transfer state changed:\n"
      "old state = %u, state = %u, reason = %u\n"
      "\tincoming = %s, in_stream = %s, out_stream = %s",
      self->priv->state, state, reason,
      self->priv->incoming ? "yes" : "no",
      self->priv->in_stream ? "present" : "not present",
      self->priv->out_stream ? "present" : "not present");

  self->priv->state = state;
  self->priv->state_change_reason = reason;

  /* If the channel is open AND we have the socket path, we can start the
   * transfer. The socket path could be NULL if we are not doing the actual
   * data transfer but are just an observer for the channel.
   */
  if (state == TP_FILE_TRANSFER_STATE_OPEN &&
      self->priv->socket_address != NULL)
    tp_file_start_transfer (EMPATHY_TP_FILE (weak_object));

  if (state == TP_FILE_TRANSFER_STATE_COMPLETED)
    ft_operation_close_clean (EMPATHY_TP_FILE (weak_object));

  if (state == TP_FILE_TRANSFER_STATE_CANCELLED)
    {
      error = error_from_state_change_reason (self->priv->state_change_reason);
      ft_operation_close_with_error (EMPATHY_TP_FILE (weak_object), error);
      g_clear_error (&error);
    }
}
static void
channel_closed_cb (TpChannel *proxy,
    const GError *error,
    gpointer user_data,
    GObject *weak_object)
{
  EmpathyTpFile *self = EMPATHY_TP_FILE (weak_object);
  gboolean cancel = GPOINTER_TO_INT (user_data);

  DEBUG ("Channel is closed, should cancel %s", cancel ? "True" : "False");

  if (self->priv->cancellable != NULL &&
      !g_cancellable_is_cancelled (self->priv->cancellable) && cancel)
    g_cancellable_cancel (self->priv->cancellable);
}
static void
tp_file_transferred_bytes_changed_cb (TpChannel *proxy,
    guint64 count,
    gpointer user_data,
    GObject *weak_object)
{
  EmpathyTpFile *self = (EmpathyTpFile *) weak_object;

  /* don't notify for 0 bytes count */
  if (count == 0)
    return;

  /* notify clients */
  if (self->priv->progress_callback != NULL)
    self->priv->progress_callback (EMPATHY_TP_FILE (weak_object),
        count, self->priv->progress_user_data);
}
static void
ft_operation_provide_or_accept_file_cb (TpChannel *proxy,
    const GValue *address,
    const GError *error,
    gpointer user_data,
    GObject *weak_object)
{
  EmpathyTpFile *self = EMPATHY_TP_FILE (weak_object);
  GError *myerr = NULL;

  g_cancellable_set_error_if_cancelled (self->priv->cancellable, &myerr);

  if (error != NULL)
    {
      if (myerr != NULL)
        {
          /* if we were both cancelled and failed when calling the method,
          * report the method error.
          */
          g_clear_error (&myerr);
        }

      myerr = g_error_copy (error);
    }

  if (myerr != NULL)
    {
      DEBUG ("Error: %s", myerr->message);
      ft_operation_close_with_error (self, myerr);
      g_clear_error (&myerr);
      return;
    }

  if (G_VALUE_TYPE (address) == DBUS_TYPE_G_UCHAR_ARRAY)
    {
      self->priv->socket_address = g_value_dup_boxed (address);
    }
  else if (G_VALUE_TYPE (address) == G_TYPE_STRING)
    {
      /* Old bugged version of telepathy-salut used to store the address
       * as a 's' instead of an 'ay' */
      const gchar *path;

      path = g_value_get_string (address);
      self->priv->socket_address = g_array_sized_new (TRUE, FALSE,
          sizeof (gchar), strlen (path));
      g_array_insert_vals (self->priv->socket_address, 0, path, strlen (path));
    }
  else if (G_VALUE_TYPE (address) == TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4)
    {
      GValueArray *val_array;
      GValue *v;
      const char *addr;

      val_array = g_value_get_boxed (address);

      /* IPV4 address */
      v = g_value_array_get_nth (val_array, 0);
      addr = g_value_get_string (v);
      self->priv->socket_address = g_array_sized_new (TRUE, FALSE,
          sizeof (gchar), strlen (addr));
      g_array_insert_vals (self->priv->socket_address, 0, addr, strlen (addr));

      /* port number */
      v = g_value_array_get_nth (val_array, 1);
      self->priv->port = g_value_get_uint (v);
    }

  DEBUG ("Got socket address: %s, port (not zero if IPV4): %d",
      self->priv->socket_address->data, self->priv->port);

  /* if the channel is already open, start the transfer now, otherwise,
   * wait for the state change signal.
   */
  if (self->priv->state == TP_FILE_TRANSFER_STATE_OPEN)
    tp_file_start_transfer (self);
}