Example #1
0
static void
cockpit_fake_manager_init_async (GAsyncInitable *initable,
                                 int io_priority,
                                 GCancellable *cancellable,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
{
  CockpitFakeManager *self = COCKPIT_FAKE_MANAGER (initable);
  InitAsyncData *data;

  g_return_if_fail (self->initializing == NULL);

  g_debug ("fakemanager: initializing async");

  self->initializing = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                                  cockpit_fake_manager_init_async);

  if (cancellable)
    {
      data = g_new0 (InitAsyncData, 1);
      data->cancellable = g_object_ref (cancellable);
      g_simple_async_result_set_op_res_gpointer (self->initializing, data, init_async_data_free);
      data->sig_cancelled = g_cancellable_connect (cancellable, G_CALLBACK (on_init_async_cancelled), self, NULL);
    }

  /* The initialization started in constructor, may already be done? */
  if (self->bus_appears > 0 || self->bus_disappears > 0)
    maybe_complete_async_init (self);
}
Example #2
0
/**
 * g_vfs_ftp_connection_accept_data_connection:
 * @conn: a listening connection
 * @cancellable: cancellable to interrupt wait
 * @error: %NULL or location to take a potential error
 *
 * Opens a data connection for @conn by accepting an incoming connection on the
 * address it is listening on via g_vfs_ftp_connection_listen_data_connection(),
 * which must have been called prior to this function.
 * If this function succeeds, a data connection will have been opened, and calls
 * to g_vfs_ftp_connection_get_data_stream() will work.
 *
 * Returns: %TRUE if a connection was successfully acquired
 **/
gboolean
g_vfs_ftp_connection_accept_data_connection (GVfsFtpConnection *conn,
                                             GCancellable *     cancellable,
                                             GError **          error)
{
  GSocket *accepted;
  GCancellable *timer;
  gulong cancel_cb_id;
  GIOCondition condition;

  g_return_val_if_fail (conn != NULL, FALSE);
  g_return_val_if_fail (conn->data == NULL, FALSE);
  g_return_val_if_fail (G_IS_SOCKET (conn->listen_socket), FALSE);

  timer = g_cancellable_new ();
  cancel_cb_id = g_cancellable_connect (cancellable, 
                                        G_CALLBACK (cancel_timer_cb),
                                        timer,
                                        NULL);
  g_object_ref (timer);
  g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
                              G_VFS_FTP_TIMEOUT_IN_SECONDS,
                              cancel_cancellable,
                              timer,
                              g_object_unref);

  condition = g_socket_condition_wait (conn->listen_socket, G_IO_IN, timer, error);

  g_cancellable_disconnect (cancellable, cancel_cb_id);
  g_object_unref (timer);

  if ((condition & G_IO_IN) == 0)
    {
      if (g_cancellable_is_cancelled (timer) &&
          !g_cancellable_is_cancelled (cancellable))
        {
          g_clear_error (error);
          g_set_error_literal (error, 
                               G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
                               _("Failed to create active FTP connection. "
                                 "Maybe your router does not support this?"));
        }
      else if (error && *error == NULL)
        {
          g_set_error_literal (error, 
                               G_IO_ERROR, G_IO_ERROR_HOST_NOT_FOUND,
                               _("Failed to create active FTP connection."));
        }
      return FALSE;
    }

  accepted = g_socket_accept (conn->listen_socket, cancellable, error);
  if (accepted == NULL)
    return FALSE;

  conn->data = G_IO_STREAM (g_socket_connection_factory_create_connection (accepted));
  g_object_unref (accepted);
  enable_nodelay (G_SOCKET_CONNECTION (conn->data));
  return TRUE;
}
Example #3
0
static TrackedTask *
progress_lookup_or_create_task (GCancellable *cancellable)
{
	TrackedTask *task;

	if (tracked_tasks == NULL)
		tracked_tasks = g_hash_table_new_full (g_direct_hash, g_direct_equal,
		                                       NULL, tracked_task_free);

	task = g_hash_table_lookup (tracked_tasks, cancellable);
	if (task == NULL) {
		if (g_cancellable_is_cancelled (cancellable))
			return NULL;

		task = g_new0 (TrackedTask, 1);
		task->cancellable = cancellable;
		g_object_weak_ref (G_OBJECT (task->cancellable),
		                   on_cancellable_gone, task);
		task->parts = g_queue_new ();

		g_hash_table_insert (tracked_tasks, cancellable, task);
		task->cancelled_sig = g_cancellable_connect (cancellable,
		                                             G_CALLBACK (on_cancellable_cancelled),
		                                             task, NULL);
	}

	return task;
}
gboolean
pk_backend_transaction_initialize (PkBackend *self, alpm_transflag_t flags,
				   GError **error)
{
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (alpm != NULL, FALSE);
	g_return_val_if_fail (cancellable != NULL, FALSE);

	if (alpm_trans_init (alpm, flags) < 0) {
		alpm_errno_t errno = alpm_errno (alpm);
		g_set_error_literal (error, ALPM_ERROR, errno,
				     alpm_strerror (errno));
		return FALSE;
	}

	alpm_option_set_eventcb (alpm, pk_backend_transaction_event_cb);
	alpm_option_set_questioncb (alpm, pk_backend_transaction_conv_cb);
	alpm_option_set_progresscb (alpm, pk_backend_transaction_progress_cb);

	alpm_option_set_dlcb (alpm, pk_backend_transaction_dlcb);
	alpm_option_set_totaldlcb (alpm, pk_backend_transaction_totaldlcb);

	g_cancellable_connect (cancellable,
			       G_CALLBACK (transaction_cancelled_cb),
			       self, NULL);

	return TRUE;
}
Example #5
0
static WritebackData *
writeback_data_new (TrackerController       *controller,
                    GList                   *writeback_handlers,
                    TrackerSparqlConnection *connection,
                    const gchar             *subject,
                    GPtrArray               *results,
                    GDBusMethodInvocation   *invocation,
                    TrackerDBusRequest      *request)
{
	WritebackData *data;

	data = g_slice_new (WritebackData);
	data->cancellable = g_cancellable_new ();
	data->controller = g_object_ref (controller);
	data->subject = g_strdup (subject);
	data->results = g_ptr_array_ref (results);
	data->invocation = invocation;
	data->connection = g_object_ref (connection);
	data->writeback_handlers = writeback_handlers;
	data->request = request;
	data->error = NULL;

	data->cancel_id = g_cancellable_connect (data->cancellable,
	                                         G_CALLBACK (task_cancellable_cancelled_cb),
	                                         data, NULL);

	return data;
}
Example #6
0
/**
 * gsound_context_play_simple: (skip)
 * @context: A #GSoundContext
 * @cancellable: (allow-none): A #GCancellable, or %NULL
 * @error: Return location for error, or %NULL
 * @...: Arguments
 * 
 * Returns: %TRUE on success, or %FALSE, populating @error
 */
gboolean
gsound_context_play_simple (GSoundContext *self,
                            GCancellable *cancellable,
                            GError **error,
                            ...)
{
    ca_proplist *pl;
    va_list args;
    int res;
    
    g_return_val_if_fail(GSOUND_IS_CONTEXT(self), FALSE);

    if ((res = ca_proplist_create(&pl)) != CA_SUCCESS)
        return test_return(res, error);

    va_start(args, error);
    var_args_to_prop_list (args, pl);
    va_end(args);

    res = ca_context_play_full(self->priv->ca,
                               GPOINTER_TO_INT(cancellable),
                               pl, NULL, NULL);

    if (cancellable)
        g_cancellable_connect(cancellable,
                              G_CALLBACK(on_cancellable_cancelled),
                              g_object_ref(self),
                              g_object_unref);

    ca_proplist_destroy(pl);

    return test_return(res, error);
}
static void
activate_ready (MMBaseModem *modem,
                GAsyncResult *res,
                Dial3gppContext *ctx)
{
    GError *error = NULL;

    /* From now on, if we get cancelled, we'll need to run the connection
     * reset ourselves just in case */

    if (!mm_base_modem_at_command_full_finish (modem, res, &error)) {
        g_simple_async_result_take_error (ctx->result, error);
        g_simple_async_result_complete (ctx->result);
        g_object_unref (ctx->result);
        return;
    }

    /* We will now setup a timeout and keep the context in the bearer's private.
     * Reports of modem being connected will arrive via unsolicited messages. */
    g_assert (ctx->self->priv->connect_pending == NULL);
    ctx->self->priv->connect_pending = ctx;
    ctx->self->priv->connect_pending_id = g_timeout_add_seconds (30,
                                                                 (GSourceFunc)connect_timed_out_cb,
                                                                 ctx->self);
    ctx->self->priv->connect_cancellable_id = g_cancellable_connect (ctx->cancellable,
                                                                     G_CALLBACK (connect_cancelled_cb),
                                                                     ctx->self,
                                                                     NULL);
}
Example #8
0
static void
mm_base_modem_init (MMBaseModem *self)
{
    /* Initialize private data */
    self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
                                              MM_TYPE_BASE_MODEM,
                                              MMBaseModemPrivate);

    /* Setup authorization provider */
    self->priv->authp = mm_auth_get_provider ();
    self->priv->authp_cancellable = g_cancellable_new ();

    /* Setup modem-wide cancellable */
    self->priv->cancellable = g_cancellable_new ();
    self->priv->invalid_if_cancelled =
        g_cancellable_connect (self->priv->cancellable,
                               G_CALLBACK (base_modem_cancelled),
                               self,
                               NULL);

    self->priv->ports = g_hash_table_new_full (g_str_hash,
                                               g_str_equal,
                                               g_free,
                                               g_object_unref);
}
Example #9
0
/**
 * gsound_context_play_simplev:
 * @context: A #GSoundContext
 * @attrs: (element-type utf8 utf8): Attributes
 * @cancellable: (allow-none): A #GCancellable
 * @error: Return location for error
 * 
 * Returns: %TRUE on success, %FALSE on error
 * 
 * Rename to: gsound_context_play_simple
 */
gboolean
gsound_context_play_simplev(GSoundContext *self,
                            GHashTable *attrs,
                            GCancellable *cancellable,
                            GError **error)
{
    ca_proplist *proplist;
    int res = ca_proplist_create(&proplist);
    if (!test_return (res, error))
        return FALSE;
    
    hash_table_to_prop_list (attrs, proplist);

    res = ca_context_play_full(self->priv->ca,
                               GPOINTER_TO_INT(cancellable),
                               proplist, NULL, NULL);

    if (cancellable)
        g_cancellable_connect(cancellable,
                              G_CALLBACK(on_cancellable_cancelled),
                              g_object_ref(self),
                              g_object_unref);

    ca_proplist_destroy(proplist);
    
    return test_return (res, error);
}
Example #10
0
GSource *
_g_fd_source_new (int           fd,
		  gushort       events,
		  GCancellable *cancellable)
{
  GSource *source;
  FDSource *fd_source;

  source = g_source_new (&fd_source_funcs, sizeof (FDSource));
  fd_source = (FDSource *)source;

  if (cancellable)
    fd_source->cancellable = g_object_ref (cancellable);
  
  fd_source->pollfd.fd = fd;
  fd_source->pollfd.events = events;
  g_source_add_poll (source, &fd_source->pollfd);

  if (cancellable)
    fd_source->cancelled_tag =
      g_cancellable_connect (cancellable, 
			     (GCallback)fd_source_cancelled_cb,
			     NULL, NULL);
  
  return source;
}
static void
fetch_items(GTask* task, gpointer source, gpointer task_data, GCancellable* cancel)
{
    g_assert(GT_IS_SEARCH_GAME_CONTAINER(source));

    GtSearchGameContainer* self = GT_SEARCH_GAME_CONTAINER(source);
    GtSearchGameContainerPrivate* priv = gt_search_game_container_get_instance_private(self);

    g_assert(G_IS_CANCELLABLE(cancel));
    g_assert(G_IS_TASK(task));

    if (g_task_return_error_if_cancelled(task))
        return;

    if (utils_str_empty(priv->query))
    {
        g_task_return_pointer(task, NULL, NULL);
        return;
    }

    g_assert_nonnull(task_data);

    FetchItemsData* data = task_data;

    g_mutex_lock(&priv->mutex);

    gint64 end_time = g_get_monotonic_time() + SEARCH_DELAY;

    g_cancellable_connect(cancel, G_CALLBACK(cancelled_cb), self, NULL);

    while (!g_cancellable_is_cancelled(cancel))
    {
        if (!g_cond_wait_until(&priv->cond, &priv->mutex, end_time))
        {
            /* We weren't cancelled */

            g_assert(!utils_str_empty(priv->query));

            GError* err = NULL;

            GList* items = data->offset == 0 ? gt_twitch_search_games(main_app->twitch,
                priv->query, data->amount, data->offset, &err) : NULL;

            if (err)
                g_task_return_error(task, err);
            else
                g_task_return_pointer(task, items, (GDestroyNotify) gt_game_list_free);

            g_mutex_unlock(&priv->mutex);

            return;
        }
    }

    /* We were cancelled */
    g_assert(g_task_return_error_if_cancelled(task));

    g_mutex_unlock(&priv->mutex);
}
Example #12
0
void
mm_base_modem_at_command_full (MMBaseModem *self,
                               MMAtSerialPort *port,
                               const gchar *command,
                               guint timeout,
                               gboolean allow_cached,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    AtCommandContext *ctx;

    /* Ensure that we have an open port */
    if (!abort_async_if_port_unusable (self, port, callback, user_data))
        return;

    ctx = g_new0 (AtCommandContext, 1);
    ctx->self = g_object_ref (self);
    ctx->port = g_object_ref (port);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                  callback,
                  user_data,
                  mm_base_modem_at_command_full);

    /* Setup cancellables */
    ctx->modem_cancellable = mm_base_modem_get_cancellable (self);
    ctx->user_cancellable = cancellable ? g_object_ref (cancellable) : NULL;
    if (!ctx->user_cancellable)
        /* Just the modem-wide one, use it directly */
        ctx->cancellable = g_object_ref (ctx->modem_cancellable);
    else {
        /* Use the user provided one, which will also get cancelled if the modem
         * wide-one gets cancelled */
        ctx->cancellable = g_object_ref (ctx->user_cancellable);
        ctx->cancelled_id = g_cancellable_connect (ctx->modem_cancellable,
                            G_CALLBACK (modem_cancellable_cancelled),
                            ctx->user_cancellable,
                            NULL);
    }


    /* Go on with the command */
    if (allow_cached)
        mm_at_serial_port_queue_command_cached (
            port,
            command,
            timeout,
            ctx->cancellable,
            (MMAtSerialResponseFn)at_command_parse_response,
            ctx);
    else
        mm_at_serial_port_queue_command (
            port,
            command,
            timeout,
            ctx->cancellable,
            (MMAtSerialResponseFn)at_command_parse_response,
            ctx);
}
 RegisterWindowCbData(uGlobalMenuBar *aMenu,
                      GCancellable *aCancellable):
                      mMenu(aMenu),
                      mCancellable(aCancellable)
 {
   g_object_ref(mCancellable);
   mID = g_cancellable_connect(mCancellable, G_CALLBACK(Cancelled), this, nullptr);
 }
void
goa_http_client_check (GoaHttpClient       *self,
                       const gchar         *uri,
                       const gchar         *username,
                       const gchar         *password,
                       gboolean             accept_ssl_errors,
                       GCancellable        *cancellable,
                       GAsyncReadyCallback  callback,
                       gpointer             user_data)
{
  CheckData *data;
  CheckAuthData *auth;
  SoupLogger *logger;

  g_return_if_fail (GOA_IS_HTTP_CLIENT (self));
  g_return_if_fail (uri != NULL && uri[0] != '\0');
  g_return_if_fail (username != NULL && username[0] != '\0');
  g_return_if_fail (password != NULL && password[0] != '\0');
  g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

  data = g_slice_new0 (CheckData);
  data->res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, goa_http_client_check);
  data->session = soup_session_new_with_options (SOUP_SESSION_SSL_STRICT, FALSE,
                                                 NULL);

  logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
  soup_logger_set_printer (logger, http_client_log_printer, NULL, NULL);
  soup_session_add_feature (data->session, SOUP_SESSION_FEATURE (logger));
  g_object_unref (logger);

  data->accept_ssl_errors = accept_ssl_errors;

  data->msg = soup_message_new (SOUP_METHOD_GET, uri);
  soup_message_headers_append (data->msg->request_headers, "Connection", "close");

  if (cancellable != NULL)
    {
      data->cancellable = g_object_ref (cancellable);
      data->cancellable_id = g_cancellable_connect (data->cancellable,
                                                    G_CALLBACK (http_client_check_cancelled_cb),
                                                    data,
                                                    NULL);
      g_simple_async_result_set_check_cancellable (data->res, data->cancellable);
    }

  auth = g_slice_new0 (CheckAuthData);
  auth->username = g_strdup (username);
  auth->password = g_strdup (password);
  g_signal_connect_data (data->session,
                         "authenticate",
                         G_CALLBACK (http_client_authenticate),
                         auth,
                         http_client_check_auth_data_free,
                         0);

  g_signal_connect (data->session, "request-started", G_CALLBACK (http_client_request_started), data);
  soup_session_queue_message (data->session, data->msg, http_client_check_response_cb, data);
}
Example #15
0
static void
seahorse_hkp_source_search_async (SeahorseServerSource *source,
                                  const gchar *match,
                                  GcrSimpleCollection *results,
                                  GCancellable *cancellable,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
{
	SeahorseHKPSource *self = SEAHORSE_HKP_SOURCE (source);
	source_search_closure *closure;
	GSimpleAsyncResult *res;
	SoupMessage *message;
	GHashTable *form;
	SoupURI *uri;
	gchar hexfpr[11];

	res = g_simple_async_result_new (G_OBJECT (source), callback, user_data,
	                                 seahorse_hkp_source_search_async);
	closure = g_new0 (source_search_closure, 1);
	closure->source = g_object_ref (self);
	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
	closure->session = create_hkp_soup_session ();
	closure->results = g_object_ref (results);
	g_simple_async_result_set_op_res_gpointer (res, closure, source_search_free);

	uri = get_http_server_uri (self, "/pks/lookup");
	g_return_if_fail (uri);

	form = g_hash_table_new (g_str_hash, g_str_equal);
	g_hash_table_insert (form, "op", "index");

	if (is_hex_keyid (match)) {
		strncpy (hexfpr, "0x", 3);
		strncpy (hexfpr + 2, match, 9);
		g_hash_table_insert (form, "search", hexfpr);
	} else {
		g_hash_table_insert (form, "search", (char *)match);
	}

	g_hash_table_insert (form, "fingerprint", "on");

	soup_uri_set_query_from_form (uri, form);
	g_hash_table_destroy (form);

	message = soup_message_new_from_uri ("GET", uri);
	soup_session_queue_message (closure->session, message,
	                            on_search_message_complete, g_object_ref (res));

	seahorse_progress_prep_and_begin (cancellable, message, NULL);

	if (cancellable)
		closure->cancelled_sig = g_cancellable_connect (cancellable,
		                                                G_CALLBACK (on_session_cancelled),
		                                                closure->session, NULL);

	soup_uri_free (uri);
	g_object_unref (res);
}
Example #16
0
static TrackerExtractTask *
extract_task_new (TrackerExtract *extract,
                  const gchar    *uri,
                  const gchar    *mimetype,
                  const gchar    *graph,
                  GCancellable   *cancellable,
                  GAsyncResult   *res,
                  GError        **error)
{
	TrackerExtractTask *task;
	gchar *mimetype_used;

	if (!mimetype || !*mimetype) {
		GFile *file;
		GFileInfo *info;
		GError *internal_error = NULL;

		file = g_file_new_for_uri (uri);
		info = g_file_query_info (file,
		                          G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
		                          G_FILE_QUERY_INFO_NONE,
		                          NULL,
		                          &internal_error);

		g_object_unref (file);

		if (internal_error) {
			g_propagate_error (error, internal_error);
			return NULL;
		}

		mimetype_used = g_strdup (g_file_info_get_content_type (info));
		g_object_unref (info);
		g_message ("MIME type guessed as '%s' (from GIO)", mimetype_used);
	} else {
		mimetype_used = g_strdup (mimetype);
		g_message ("MIME type passed to us as '%s'", mimetype_used);
	}

	task = g_slice_new0 (TrackerExtractTask);
	task->cancellable = (cancellable) ? g_object_ref (cancellable) : NULL;
	task->res = (res) ? g_object_ref (res) : NULL;
	task->file = g_strdup (uri);
	task->mimetype = mimetype_used;
	task->graph = g_strdup (graph);
	task->extract = extract;

	if (task->cancellable) {
		task->signal_id = g_cancellable_connect (cancellable,
		                                         G_CALLBACK (task_cancellable_cancelled_cb),
		                                         task, NULL);
	}

	return task;
}
void
mm_base_modem_at_sequence_full (MMBaseModem *self,
                                MMAtSerialPort *port,
                                const MMBaseModemAtCommand *sequence,
                                gpointer response_processor_context,
                                GDestroyNotify response_processor_context_free,
                                GCancellable *cancellable,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
{
    AtSequenceContext *ctx;

    /* Ensure that we have an open port */
    if (!abort_async_if_port_unusable (self, port, callback, user_data))
        return;

    /* Setup context */
    ctx = g_new0 (AtSequenceContext, 1);
    ctx->self = g_object_ref (self);
    ctx->port = g_object_ref (port);
    ctx->simple = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             mm_base_modem_at_sequence_full);
    ctx->current = ctx->sequence = sequence;
    ctx->response_processor_context = response_processor_context;
    ctx->response_processor_context_free = response_processor_context_free;

    /* Setup cancellables */
    ctx->modem_cancellable = mm_base_modem_get_cancellable (self);
    ctx->user_cancellable = cancellable ? g_object_ref (cancellable) : NULL;
    if (!ctx->user_cancellable)
        /* Just the modem-wide one, use it directly */
        ctx->cancellable = g_object_ref (ctx->modem_cancellable);
    else {
        /* Use the user provided one, which will also get cancelled if the modem
         * wide-one gets cancelled */
        ctx->cancellable = g_object_ref (ctx->user_cancellable);
        ctx->cancelled_id = g_cancellable_connect (ctx->modem_cancellable,
                                                   G_CALLBACK (modem_cancellable_cancelled),
                                                   ctx->user_cancellable,
                                                   NULL);
    }

    /* Go on with the first one in the sequence */
    mm_at_serial_port_queue_command (
        ctx->port,
        ctx->current->command,
        ctx->current->timeout,
        FALSE,
        ctx->cancellable,
        (MMAtSerialResponseFn)at_sequence_parse_response,
        ctx);
}
Example #18
0
static void
exporter_display_chooser (GcrCertificateExporter *self)
{
	GtkFileFilter* filter;
	GtkWidget *dialog;
	gchar *filename;

	g_assert (!self->pv->chooser_dialog);

	dialog = gtk_file_chooser_dialog_new (_("Export certificate"),
	                     NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
	                     _("_Cancel"), GTK_RESPONSE_CANCEL,
	                     _("_Save"), GTK_RESPONSE_ACCEPT,
	                     NULL);

	self->pv->chooser_dialog = g_object_ref_sink(dialog);
	gtk_dialog_set_default_response (GTK_DIALOG (dialog),
	                                 GTK_RESPONSE_ACCEPT);
	gtk_file_chooser_set_local_only (self->pv->chooser_dialog, FALSE);

	filter = gtk_file_filter_new ();
	gtk_file_filter_set_name (filter, _("Certificate files"));
	gtk_file_filter_add_mime_type (filter, "application/x-x509-ca-cert");
	gtk_file_filter_add_mime_type (filter, "application/x-x509-user-cert");
	gtk_file_filter_add_mime_type (filter, "application/pkix-cert");
	gtk_file_filter_add_pattern (filter, "*.cer");
	gtk_file_filter_add_pattern (filter, "*.crt");
	g_object_set_data (G_OBJECT (filter), "prepare-data-func", prepare_data_for_der);
	gtk_file_chooser_add_filter (self->pv->chooser_dialog, filter);
	gtk_file_chooser_set_filter (self->pv->chooser_dialog, filter);

	filter = gtk_file_filter_new ();
	gtk_file_filter_set_name (filter, _("PEM files"));
	gtk_file_filter_add_mime_type (filter, "text/plain");
	gtk_file_filter_add_pattern (filter, "*.pem");
	g_object_set_data (G_OBJECT (filter), "prepare-data-func", prepare_data_for_pem);
	gtk_file_chooser_add_filter (self->pv->chooser_dialog, filter);

	filename = g_strconcat (self->pv->label, ".crt", NULL);
	g_strdelimit (filename, BAD_FILENAME_CHARS, '_');
	gtk_file_chooser_set_current_name (self->pv->chooser_dialog, filename);
	g_free (filename);

	g_signal_connect (self->pv->chooser_dialog, "response",
	                  G_CALLBACK (on_chooser_dialog_response), self);
	if (self->pv->cancellable)
		g_cancellable_connect (self->pv->cancellable,
		                       G_CALLBACK (on_cancel_chooser_dialog), self, NULL);

	gtk_widget_show (GTK_WIDGET (self->pv->chooser_dialog));
}
Example #19
0
/**
 * gsound_context_play_full: (skip)
 * @context: A #GSoundContext
 * @cancellable: (allow-none): A #GCancellable, or %NULL
 * @callback: (scope async): callback
 * @user_data: User data passed to @callback
 * @...: Attributes
 * 
 */
void
gsound_context_play_full(GSoundContext *self,
                         GCancellable *cancellable,
                         GAsyncReadyCallback callback,
                         gpointer user_data,
                         ...)
{
    GError *inner_error = NULL;
    ca_proplist *proplist;
    va_list args;
    int res = ca_proplist_create(&proplist);
    if (!test_return (res, &inner_error))
    {
        g_simple_async_report_take_gerror_in_idle (G_OBJECT(self),
                                                   callback,
                                                   user_data,
                                                   inner_error);
    }

    va_start(args, user_data);
    var_args_to_prop_list (args, proplist);
    va_end(args);

    GSimpleAsyncResult *result = g_simple_async_result_new(G_OBJECT(self),
                                                           callback,
                                                           user_data,
                                                           NULL /*FIXME*/);

    res = ca_context_play_full(self->priv->ca,
                               GPOINTER_TO_INT(cancellable),
                               proplist,
                               on_ca_play_full_finished,
                               result);

    if (cancellable)
        g_cancellable_connect(cancellable,
                              G_CALLBACK(on_cancellable_cancelled),
                              g_object_ref(self),
                              g_object_unref);

    ca_proplist_destroy(proplist);

    if (!test_return (res, &inner_error))
    {
        g_simple_async_report_take_gerror_in_idle (G_OBJECT(self),
                                                   callback,
                                                   user_data,
                                                   inner_error);
        g_object_unref(result);
    }
}
Example #20
0
void
fr_process_execute (FrProcess           *process,
		    GCancellable        *cancellable,
		    GAsyncReadyCallback  callback,
		    gpointer             user_data)
{
	ExecuteData *exec_data;

	g_return_if_fail (! process->priv->running);

	execute_data_free (process->priv->exec_data);

	process->priv->exec_data = exec_data = g_new0 (ExecuteData, 1);
	exec_data->process = g_object_ref (process);
	exec_data->cancellable = _g_object_ref (cancellable);
	exec_data->cancel_id = 0;
	exec_data->result = g_simple_async_result_new (G_OBJECT (process),
						       callback,
						       user_data,
						       fr_process_execute);

        g_simple_async_result_set_op_res_gpointer (exec_data->result, exec_data, NULL);

	if (! process->restart)
		process->priv->current_charset = -1;

	if (cancellable != NULL) {
		GError *error = NULL;

		if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
			exec_data->error = fr_error_new (FR_ERROR_STOPPED, 0, error);
			_fr_process_execute_complete_in_idle (exec_data);

			g_error_free (error);
			return;
		}

		exec_data->cancel_id = g_cancellable_connect (cancellable,
							      G_CALLBACK (execute_cancelled_cb),
							      exec_data,
							      NULL);
	}

	_fr_process_start (exec_data);
}
Example #21
0
void
goa_alarm_set_time (GoaAlarm *self, GDateTime *time, GCancellable *cancellable)
{
  if (g_cancellable_is_cancelled (cancellable))
    return;

  if (self->priv->cancellable != NULL && self->priv->cancellable != cancellable)
    g_cancellable_cancel (self->priv->cancellable);

  if (cancellable != NULL)
    g_object_ref (cancellable);

  if (self->priv->cancelled_id != 0)
    g_cancellable_disconnect (self->priv->cancellable, self->priv->cancelled_id);

  g_clear_object (&self->priv->cancellable);

  if (cancellable != NULL)
    self->priv->cancellable = cancellable;
  else
    self->priv->cancellable = g_cancellable_new ();

  self->priv->cancelled_id = g_cancellable_connect (self->priv->cancellable,
                                                    G_CALLBACK (on_cancelled),
                                                    self, NULL);

  g_date_time_ref (time);

  if (self->priv->time != NULL)
    g_date_time_unref (self->priv->time);

  self->priv->time = time;

  self->priv->context = g_main_context_ref (g_main_context_default ());

  g_object_notify (G_OBJECT (self), "time");

  schedule_wakeups (self);

  /* Wake up right away, in case it's already expired leaving the gate */
  schedule_immediate_wakeup (self);
}
Example #22
0
static void
on_create_file_ready (GObject *source, GAsyncResult *res, gpointer user_data)
{
	GcrCertificateExporter *self = GCR_CERTIFICATE_EXPORTER (user_data);
	GFileOutputStream *os;
	GtkWidget *dialog;

	os = g_file_create_finish (self->pv->output_file, res, &self->pv->error);

	/* Try again this time replacing the file */
	if (g_error_matches (self->pv->error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
		g_clear_error (&self->pv->error);

		dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (self->pv->chooser_dialog),
		     GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
		     GTK_BUTTONS_NONE, "<b>%s</b>\n\n%s",
		     _("A file already exists with this name."),
		     _("Do you want to replace it with a new file?"));
		gtk_dialog_add_buttons (GTK_DIALOG (dialog),
		                        _("_Cancel"), GTK_RESPONSE_CANCEL,
		                        _("_Replace"), GTK_RESPONSE_ACCEPT, NULL);

		g_signal_connect (dialog, "response",
		                  G_CALLBACK (on_replace_dialog_response), self);
		if (self->pv->cancellable)
			g_cancellable_connect (self->pv->cancellable,
			                       G_CALLBACK (on_cancel_replace_dialog),
			                       g_object_ref (dialog), g_object_unref);
		gtk_widget_show (dialog);

		return;
	}

	if (self->pv->error) {
		complete_async_result (self);
		return;
	}

	write_to_outputstream (self, G_OUTPUT_STREAM (os));
}
static void
initiate_authentication (PolkitAgentListener  *listener,
                         const gchar          *action_id,
                         const gchar          *message,
                         const gchar          *icon_name,
                         PolkitDetails        *details,
                         const gchar          *cookie,
                         GList                *identities,
                         GCancellable         *cancellable,
                         GAsyncReadyCallback   callback,
                         gpointer              user_data)
{
    ShellPolkitAuthenticationAgent *agent = SHELL_POLKIT_AUTHENTICATION_AGENT (listener);
    AuthRequest *request;

    request = g_new0 (AuthRequest, 1);
    request->agent = agent;
    request->action_id = g_strdup (action_id);
    request->message = g_strdup (message);
    request->icon_name = g_strdup (icon_name);
    request->details = g_object_ref (details);
    request->cookie = g_strdup (cookie);
    request->identities = g_list_copy (identities);
    g_list_foreach (request->identities, (GFunc) g_object_ref, NULL);
    request->simple = g_simple_async_result_new (G_OBJECT (listener),
                      callback,
                      user_data,
                      initiate_authentication);
    request->cancellable = cancellable;
    request->handler_id = g_cancellable_connect (request->cancellable,
                          G_CALLBACK (on_request_cancelled),
                          request,
                          NULL); /* GDestroyNotify for request */

    print_debug ("SCHEDULING %s cookie %s", request->action_id, request->cookie);
    agent->scheduled_requests = g_list_append (agent->scheduled_requests, request);

    maybe_process_next_request (agent);
}
Example #24
0
static void
resolve_t_param (TotemYouTubePlugin *self, GDataEntry *entry, GtkTreeIter *iter, guint tree_view, GCancellable *cancellable)
{
	GDataLink *page_link;
	TParamData *data;

	/* We have to get the t parameter from the actual HTML video page, since Google changed how their URIs work */
	page_link = gdata_entry_look_up_link (entry, GDATA_LINK_ALTERNATE);
	g_assert (page_link != NULL);

	data = g_slice_new (TParamData);
	data->plugin = g_object_ref (self);
	data->entry = g_object_ref (entry);
	data->path = gtk_tree_model_get_path (GTK_TREE_MODEL (self->list_store[tree_view]), iter);
	data->tree_view = tree_view;
	data->cancellable = g_object_ref (cancellable);

	data->message = soup_message_new (SOUP_METHOD_GET, gdata_link_get_uri (page_link));
	data->cancelled_id = g_cancellable_connect (cancellable, (GCallback) resolve_t_param_cancelled_cb, data, NULL);

	/* Send the message. Consumes a reference to data->message after resolve_t_param_cb() finishes */
	soup_session_queue_message (self->session, data->message, (SoupSessionCallback) resolve_t_param_cb, data);
}
Example #25
0
static GSource *
seahorse_ldap_gsource_new (LDAP *ldap,
                           int ldap_op,
                           GCancellable *cancellable)
{
	GSource *gsource;
	SeahorseLdapGSource *ldap_gsource;

	gsource = g_source_new (&seahorse_ldap_gsource_funcs,
	                        sizeof (SeahorseLdapGSource));

	ldap_gsource = (SeahorseLdapGSource *)gsource;
	ldap_gsource->ldap = ldap;
	ldap_gsource->ldap_op = ldap_op;

	if (cancellable) {
		ldap_gsource->cancellable = g_object_ref (cancellable);
		ldap_gsource->cancelled_sig = g_cancellable_connect (cancellable,
		                                                     G_CALLBACK (on_ldap_gsource_cancelled),
		                                                     ldap_gsource, NULL);
	}

	return gsource;
}
Example #26
0
/**
 * gupnp_service_info_get_introspection_async_full:
 * @info: A #GUPnPServiceInfo
 * @callback: (scope async) : callback to be called when introspection object is ready.
 * @cancellable: GCancellable that can be used to cancel the call, or %NULL.
 * @user_data: user_data to be passed to the callback.
 *
 * Note that introspection object is created from the information in service
 * description document (SCPD) provided by the service so it can not be created
 * if the service does not provide an SCPD.
 *
 * If @cancellable is used to cancel the call, @callback will be called with
 * error code %G_IO_ERROR_CANCELLED.
 *
 * Since: 0.20.9
 **/
void
gupnp_service_info_get_introspection_async_full
                                (GUPnPServiceInfo                 *info,
                                 GUPnPServiceIntrospectionCallback callback,
                                 GCancellable                     *cancellable,
                                 gpointer                          user_data)
{
        GetSCPDURLData *data;
        char *scpd_url;
        SoupSession *session;

        g_return_if_fail (GUPNP_IS_SERVICE_INFO (info));
        g_return_if_fail (callback != NULL);

        data = g_slice_new (GetSCPDURLData);

        scpd_url = gupnp_service_info_get_scpd_url (info);

        data->message = NULL;
        if (scpd_url != NULL) {
                data->message = soup_message_new (SOUP_METHOD_GET, scpd_url);

                g_free (scpd_url);
        }

        if (data->message == NULL) {
                GError *error;

                error = g_error_new
                                (GUPNP_SERVER_ERROR,
                                 GUPNP_SERVER_ERROR_INVALID_URL,
                                 "No valid SCPD URL defined");

                callback (info, NULL, error, user_data);

                g_error_free (error);

                g_slice_free (GetSCPDURLData, data);

                return;
        }

        data->info      = info;
        data->callback  = callback;
        data->user_data = user_data;

        /* Send off the message */
        info->priv->pending_gets =
                g_list_prepend (info->priv->pending_gets,
                                data);

        session = gupnp_context_get_session (info->priv->context);

        soup_session_queue_message (session,
                                    data->message,
                                    (SoupSessionCallback) got_scpd_url,
                                    data);

        data->cancellable = cancellable;
        if (data->cancellable) {
                g_object_ref (cancellable);
                data->cancelled_id = g_cancellable_connect
                                (data->cancellable,
                                 G_CALLBACK (cancellable_cancelled_cb),
                                 data,
                                 NULL);
        }
}
static gboolean
watch_one_event_from_driver (GsdSmartcardManager       *self,
                             WatchSmartcardsOperation  *operation,
                             GCancellable              *cancellable,
                             GError                   **error)
{
        GsdSmartcardManagerPrivate *priv = self->priv;
        PK11SlotInfo *card, *old_card;
        CK_SLOT_ID slot_id;
        gulong handler_id;
        int old_slot_series = -1, slot_series;

        handler_id = g_cancellable_connect (cancellable,
                                            G_CALLBACK (on_watch_cancelled),
                                            operation,
                                            NULL);

        card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1));

        g_cancellable_disconnect (cancellable, handler_id);

        if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                g_warning ("smartcard event function cancelled");
                return FALSE;
        }

        if (card == NULL) {
                int error_code;

                error_code = PORT_GetError ();

                operation->number_of_consecutive_errors++;
                if (operation->number_of_consecutive_errors > 10) {
                     g_warning ("Got %d consecutive smartcard errors, so giving up.",
                                operation->number_of_consecutive_errors);

                     g_set_error (error,
                                  GSD_SMARTCARD_MANAGER_ERROR,
                                  GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
                                  "encountered unexpected error while "
                                  "waiting for smartcard events (error %x)",
                                  error_code);
                     return FALSE;
                }

                g_warning ("Got potentially spurious smartcard event error: %x.", error_code);

                g_usleep (0.5 * G_USEC_PER_SEC);
                return TRUE;
        }
        operation->number_of_consecutive_errors = 0;

        slot_id = PK11_GetSlotID (card);
        slot_series = PK11_GetSlotSeries (card);

        old_card = g_hash_table_lookup (operation->smartcards, GINT_TO_POINTER ((int) slot_id));

        /* If there is a different card in the slot now than
         * there was before, then we need to emit a removed signal
         * for the old card
         */
        if (old_card != NULL) {
                old_slot_series = PK11_GetSlotSeries (old_card);

                if (old_slot_series != slot_series) {
                        /* Card registered with slot previously is
                         * different than this card, so update its
                         * exported state to track the implicit missed
                         * removal
                         */
                        gsd_smartcard_service_sync_token (priv->service, old_card, cancellable);
                }

                g_hash_table_remove (operation->smartcards, GINT_TO_POINTER ((int) slot_id));
        }

        if (PK11_IsPresent (card)) {
                g_debug ("Detected smartcard insertion event in slot %d", (int) slot_id);

                g_hash_table_replace (operation->smartcards,
                                      GINT_TO_POINTER ((int) slot_id),
                                      PK11_ReferenceSlot (card));

                gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        } else if (old_card == NULL) {
                /* If the just removed smartcard is not known to us then
                 * ignore the removal event. NSS sends a synthentic removal
                 * event for slots that are empty at startup
                 */
                g_debug ("Detected slot %d is empty in reader", (int) slot_id);
        } else {
                g_debug ("Detected smartcard removal event in slot %d", (int) slot_id);

                /* If the just removed smartcard is known to us then
                 * we need to update its exported state to reflect the
                 * removal
                 */
                if (old_slot_series == slot_series)
                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        }

        PK11_FreeSlot (card);

        return TRUE;
}
Example #28
0
static gssize
nice_output_stream_write (GOutputStream *stream, const void *buffer, gsize count,
    GCancellable *cancellable, GError **error)
{
  NiceOutputStream *self = NICE_OUTPUT_STREAM (stream);
  const gchar* buf = buffer;
  gssize len = 0;
  gint n_sent;
  NiceAgent *agent = NULL;  /* owned */
  gulong cancel_id = 0, closed_cancel_id, writeable_id;
  WriteData *write_data;

  /* Closed streams are not writeable. */
  if (g_output_stream_is_closed (stream)) {
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
        "Stream is closed.");
    return -1;
  }

  /* Has the agent disappeared? */
  agent = g_weak_ref_get (&self->priv->agent_ref);
  if (agent == NULL) {
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
        "Stream is closed due to the NiceAgent being finalised.");
    return -1;
  }

  if (count == 0) {
    g_object_unref (agent);
    return 0;
  }

  /* FIXME: nice_agent_send() is non-blocking, which is a bit unexpected
   * since nice_agent_recv() is blocking. Currently this uses a fairly dodgy
   * GCond solution; would be much better for nice_agent_send() to block
   * properly in the main loop. */
  write_data = g_slice_new0 (WriteData);
  write_data->ref_count = 1;
  g_mutex_init (&write_data->mutex);
  g_cond_init (&write_data->cond);

  if (cancellable != NULL) {
    cancel_id = g_cancellable_connect (cancellable,
        (GCallback) write_cancelled_cb, write_data_ref (write_data),
        (GDestroyNotify) write_data_unref);
  }

  closed_cancel_id = g_cancellable_connect (self->priv->closed_cancellable,
      (GCallback) write_cancelled_cb, write_data_ref (write_data),
      (GDestroyNotify) write_data_unref);

  g_mutex_lock (&write_data->mutex);

  writeable_id = g_signal_connect_data (G_OBJECT (agent),
      "reliable-transport-writable",
      (GCallback) reliable_transport_writeable_cb, write_data_ref (write_data),
      (GClosureNotify) write_data_unref, 0);


  do {
    /* Have to unlock while calling into the agent because
     * it will take the agent lock which will cause a deadlock if one of
     * the callbacks is called.
     */
    if (g_cancellable_is_cancelled (cancellable) ||
        g_cancellable_is_cancelled (self->priv->closed_cancellable))
      break;

    write_data->writable = FALSE;
    g_mutex_unlock (&write_data->mutex);

    n_sent = nice_agent_send (agent, self->priv->stream_id,
        self->priv->component_id, count - len, buf + len);

    g_mutex_lock (&write_data->mutex);

    if (n_sent <= 0) {
      if (!write_data->writable && !write_data->cancelled)
        g_cond_wait (&write_data->cond, &write_data->mutex);
    } else if (n_sent > 0) {
      /* Success. */
      len += n_sent;
    }
  } while ((gsize) len < count);

  g_signal_handler_disconnect (G_OBJECT (agent), writeable_id);
  g_mutex_unlock (&write_data->mutex);

  if (cancel_id)
    g_cancellable_disconnect (cancellable, cancel_id);
  g_cancellable_disconnect (self->priv->closed_cancellable, closed_cancel_id);

  if (len == 0) {
    len = -1;
    if (!g_cancellable_set_error_if_cancelled (cancellable, error)) {
      if (g_cancellable_is_cancelled (self->priv->closed_cancellable))
        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
            "Stream has been removed from agent");
    }
  }

  write_data_unref (write_data);

  g_object_unref (agent);
  g_assert (len != 0);

  return len;
}
Example #29
0
static void
cockpit_polkit_agent_initiate_authentication (PolkitAgentListener *listener,
                                              const gchar *action_id,
                                              const gchar *message,
                                              const gchar *icon_name,
                                              PolkitDetails *details,
                                              const gchar *cookie,
                                              GList *identities,
                                              GCancellable *cancellable,
                                              GAsyncReadyCallback callback,
                                              gpointer user_data)
{
  CockpitPolkitAgent *self = COCKPIT_POLKIT_AGENT (listener);
  PolkitIdentity *identity = NULL;
  GSimpleAsyncResult *result = NULL;
  GString *unsupported = NULL;
  ReauthorizeCaller *caller;
  gchar *string;
  uid_t uid;
  GList *l;

  const gchar *argv[] = {
    PACKAGE_LIBEXEC_DIR "/cockpit-polkit",
    cookie,
    NULL,
  };

  g_debug ("polkit is requesting authentication");

  result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
                                      cockpit_polkit_agent_initiate_authentication);

  uid = getuid ();

  unsupported = g_string_new ("");
  for (l = identities; l != NULL; l = g_list_next (l))
    {
      if (POLKIT_IS_UNIX_USER (l->data))
        {
          if (polkit_unix_user_get_uid (l->data) == uid)
            {
              identity = g_object_ref (l->data);
              break;
            }
        }

      string = polkit_identity_to_string (l->data);
      g_string_append_printf (unsupported, "%s ", string);
      g_free (string);
    }

  if (!identity)
    {
      g_message ("cannot reauthorize identity(s): %s", unsupported->str);
      g_simple_async_result_set_error (result, POLKIT_ERROR, POLKIT_ERROR_FAILED,
                                       "Reauthorization not supported for identity");
      g_simple_async_result_complete_in_idle (result);
      goto out;
    }

  string = polkit_identity_to_string (identity);
  g_message ("Reauthorizing %s", string);
  g_free (string);

  caller = g_new0 (ReauthorizeCaller, 1);
  caller->cookie = g_strdup (cookie);
  caller->helper = cockpit_pipe_spawn (argv, NULL, NULL, COCKPIT_PIPE_FLAGS_NONE);
  caller->read_sig = g_signal_connect (caller->helper, "read", G_CALLBACK (on_helper_read), caller);
  caller->close_sig = g_signal_connect (caller->helper, "close", G_CALLBACK (on_helper_close), caller);

  caller->cancellable = g_object_ref (cancellable);
  caller->cancel_sig = g_cancellable_connect (cancellable, G_CALLBACK (on_cancelled), caller, NULL);

  caller->result = g_object_ref (result);
  caller->self = self;

  g_hash_table_replace (self->callers, caller->cookie, caller);

  g_debug ("cockpit-polkit helper starting");

out:
  if (unsupported)
    g_string_free (unsupported, TRUE);
  g_object_unref (result);
  if (identity)
    g_object_unref (identity);
}
Example #30
0
/**
 * secret_prompt_perform:
 * @self: a prompt
 * @window_id: XWindow id for parent window to be transient for
 * @return_type: the variant type of the prompt result
 * @cancellable: optional cancellation object
 * @callback: called when the operation completes
 * @user_data: data to be passed to the callback
 *
 * Runs a prompt and performs the prompting. Returns %TRUE if the prompt
 * was completed and not dismissed.
 *
 * If @window_id is non-zero then it is used as an XWindow id. The Secret
 * Service can make its prompt transient for the window with this id. In some
 * Secret Service implementations this is not possible, so the behavior
 * depending on this should degrade gracefully.
 *
 * This method will return immediately and complete asynchronously.
 */
void
secret_prompt_perform (SecretPrompt *self,
                       gulong window_id,
                       const GVariantType *return_type,
                       GCancellable *cancellable,
                       GAsyncReadyCallback callback,
                       gpointer user_data)
{
	GSimpleAsyncResult *res;
	PerformClosure *closure;
	const gchar *owner_name;
	const gchar *object_path;
	gboolean prompted;
	GDBusProxy *proxy;
	gchar *window;

	g_return_if_fail (SECRET_IS_PROMPT (self));
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

	prompted = g_atomic_int_get (&self->pv->prompted);
	if (prompted) {
		g_warning ("The prompt object has already had its prompt called.");
		return;
	}

	proxy = G_DBUS_PROXY (self);

	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
	                                 secret_prompt_perform);
	closure = g_slice_new0 (PerformClosure);
	closure->connection = g_object_ref (g_dbus_proxy_get_connection (proxy));
	closure->call_cancellable = g_cancellable_new ();
	closure->async_cancellable = cancellable ? g_object_ref (cancellable) : NULL;
	closure->return_type = return_type ? g_variant_type_copy (return_type) : NULL;
	g_simple_async_result_set_op_res_gpointer (res, closure, perform_closure_free);

	if (window_id == 0)
		window = g_strdup ("");
	else
		window = g_strdup_printf ("%lu", window_id);

	owner_name = g_dbus_proxy_get_name_owner (proxy);
	object_path = g_dbus_proxy_get_object_path (proxy);

	closure->signal = g_dbus_connection_signal_subscribe (closure->connection, owner_name,
	                                                      SECRET_PROMPT_INTERFACE,
	                                                      SECRET_PROMPT_SIGNAL_COMPLETED,
	                                                      object_path, NULL,
	                                                      G_DBUS_SIGNAL_FLAGS_NONE,
	                                                      on_prompt_completed,
	                                                      g_object_ref (res),
	                                                      g_object_unref);

	closure->watch = g_bus_watch_name_on_connection (closure->connection, owner_name,
	                                                 G_BUS_NAME_WATCHER_FLAGS_NONE, NULL,
	                                                 on_prompt_vanished,
	                                                 g_object_ref (res),
	                                                 g_object_unref);

	if (closure->async_cancellable) {
		closure->cancelled_sig = g_cancellable_connect (closure->async_cancellable,
		                                                G_CALLBACK (on_prompt_cancelled),
		                                                res, NULL);
	}

	g_dbus_proxy_call (proxy, "Prompt", g_variant_new ("(s)", window),
	                   G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
	                   closure->call_cancellable, on_prompt_prompted, g_object_ref (res));

	g_free (window);
	g_object_unref (res);
}