Example #1
0
static void emit_response (XdpImplFileChooser *object,
                           gboolean for_save,
                           const gchar *arg_destination,
                           const gchar *arg_handle,
                           guint arg_response,
                           const gchar *const *arg_uris,
                           GVariant *arg_options)
{
  g_autoptr(Request) request = lookup_request_by_handle (arg_handle);
  GVariantBuilder uris;
  GVariantBuilder results;
  g_autofree char *ruri = NULL;
  gboolean writable = TRUE;
  g_autoptr(GError) error = NULL;
  g_autoptr(GVariant) choices = NULL;
  int i;

  if (request == NULL)
    return;

  REQUEST_AUTOLOCK (request);

  if (!g_variant_lookup (arg_options, "b", "writable", &writable))
    writable = FALSE;

  g_variant_builder_init (&results, G_VARIANT_TYPE_VARDICT);

  choices = g_variant_lookup_value (arg_options, "choices", G_VARIANT_TYPE ("a(ss)"));
  if (choices)
    g_variant_builder_add (&results, "{sv}", "choices", choices);

  g_variant_builder_init (&uris, G_VARIANT_TYPE ("as"));

  for (i = 0; arg_uris[i] != NULL; i++)
    {
      const char *uri = arg_uris[i];
      ruri = register_document (uri, request->app_id, for_save, writable, &error);
      if (ruri == NULL)
        {
          g_warning ("Failed to register %s: %s\n", uri, error->message);
          g_clear_error (&error);
        }
      else
        {
          g_debug ("convert uri %s -> %s\n", uri, ruri);
          g_variant_builder_add (&uris, "s", ruri);
        }
    }

  g_variant_builder_add (&results, "{&sv}", "uris", g_variant_builder_end (&uris));

  if (request->exported)
    {
      xdp_request_emit_response (XDP_REQUEST (request),
                                 arg_response,
                                 g_variant_builder_end (&results));
      unregister_handle (arg_handle);
      request_unexport (request);
    }
}
Example #2
0
static gboolean
handle_close (XdpRequest *object,
              GDBusMethodInvocation *invocation,
              Request *request)
{
  g_autoptr(GError) error = NULL;

  REQUEST_AUTOLOCK (request);

  if (request->exported)
    {
      const char *handle = g_object_get_data (G_OBJECT (request), "impl-handle");

      if (!xdp_impl_file_chooser_call_close_sync (impl,
                                                  request->sender, request->app_id, handle,
                                                  NULL, &error))
        {
          g_dbus_method_invocation_return_gerror (invocation, error);
          return TRUE;
        }

      unregister_handle (handle);
      request_unexport (request);
    }

  xdp_request_complete_close (XDP_REQUEST (request), invocation);

  return TRUE;
}
Example #3
0
static void
print_done (GObject *source,
            GAsyncResult *result,
            gpointer data)
{
  g_autoptr(Request) request = data;
  guint response = 2;
  g_autoptr(GVariant) options = NULL;
  g_autoptr(GError) error = NULL;

  REQUEST_AUTOLOCK (request);

  if (!xdp_impl_print_call_print_finish (XDP_IMPL_PRINT (source),
                                         &response,
                                         &options,
                                         NULL,
                                         result,
                                         &error))
    {
      g_warning ("Backend call failed: %s", error->message);
    }

  if (request->exported)
    {
      GVariantBuilder opt_builder;

      g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);

      xdp_request_emit_response (XDP_REQUEST (request),
                                 response,
                                 g_variant_builder_end (&opt_builder));
      request_unexport (request);
    }
}
Example #4
0
static gboolean
handle_prepare_print (XdpPrint *object,
                      GDBusMethodInvocation *invocation,
                      const gchar *arg_parent_window,
                      const gchar *arg_title,
                      GVariant *arg_settings,
                      GVariant *arg_page_setup,
                      GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = xdp_app_info_get_id (request->app_info);
  g_autoptr(GError) error = NULL;
  g_autoptr(XdpImplRequest) impl_request = NULL;
  GVariantBuilder opt_builder;

  if (xdp_impl_lockdown_get_disable_printing (lockdown))
    {
      g_debug ("Printing disabled");
      g_dbus_method_invocation_return_error (invocation,
                                             XDG_DESKTOP_PORTAL_ERROR,
                                             XDG_DESKTOP_PORTAL_ERROR_NOT_ALLOWED,
                                             "Printing disabled");
      return TRUE;
    }

  REQUEST_AUTOLOCK (request);

  impl_request = xdp_impl_request_proxy_new_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (impl)),
                                                  G_DBUS_PROXY_FLAGS_NONE,
                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (impl)),
                                                  request->id,
                                                  NULL, &error);
  if (!impl_request)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  request_set_impl_request (request, impl_request);
  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
  xdp_filter_options (arg_options, &opt_builder,
                      prepare_print_options, G_N_ELEMENTS (prepare_print_options));
  xdp_impl_print_call_prepare_print (impl,
                                     request->id,
                                     app_id,
                                     arg_parent_window,
                                     arg_title,
                                     arg_settings,
                                     arg_page_setup,
                                     g_variant_builder_end (&opt_builder),
                                     NULL,
                                     prepare_print_done,
                                     g_object_ref (request));

  xdp_print_complete_prepare_print (object, invocation, request->id);

  return TRUE;
}
static gboolean
handle_save_file (XdpFileChooser *object,
                  GDBusMethodInvocation *invocation,
                  const gchar *arg_parent_window,
                  const gchar *arg_title,
                  GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = request->app_id;
  g_autoptr(GError) error = NULL;
  XdpImplRequest *impl_request;
  GVariantBuilder options;

  REQUEST_AUTOLOCK (request);

  g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
  xdp_filter_options (arg_options, &options,
                      save_file_options, G_N_ELEMENTS (save_file_options));

  impl_request = xdp_impl_request_proxy_new_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (impl)),
                                                  G_DBUS_PROXY_FLAGS_NONE,
                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (impl)),
                                                  request->id,
                                                  NULL, &error);
  if (!impl_request)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  g_object_set_data (G_OBJECT (request), "for-save", GINT_TO_POINTER (TRUE));

  request_set_impl_request (request, impl_request);
  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  xdp_impl_file_chooser_call_save_file (impl,
                                        request->id,
                                        app_id,
                                        arg_parent_window,
                                        arg_title,
                                        g_variant_builder_end (&options),
                                        NULL,
                                        save_file_done,
                                        g_object_ref (request));

  xdp_file_chooser_complete_open_file (object, invocation, request->id);

  return TRUE;
}
Example #6
0
static gboolean
handle_save_file (XdpFileChooser *object,
                  GDBusMethodInvocation *invocation,
                  const gchar *arg_parent_window,
                  const gchar *arg_title,
                  GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = request->app_id;
  const gchar *sender = g_dbus_method_invocation_get_sender (invocation);
  g_autoptr(GError) error = NULL;
  g_autofree char *impl_handle = NULL;
  GVariantBuilder options;

  g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
  copy_options (arg_options, &options, save_file_options, G_N_ELEMENTS (save_file_options));

  if (!xdp_impl_file_chooser_call_save_file_sync (impl,
                                                  sender, app_id,
                                                  arg_parent_window,
                                                  arg_title,
                                                  g_variant_builder_end (&options),
                                                  &impl_handle,
                                                  NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  g_object_set_data_full (G_OBJECT (request), "impl-handle", g_strdup (impl_handle), g_free);
  register_handle (impl_handle, request);

  g_signal_connect (request, "handle-close", (GCallback)handle_close, request);

  REQUEST_AUTOLOCK (request);

  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  xdp_file_chooser_complete_open_file (object, invocation, request->id);
  return TRUE;
}
Example #7
0
static gboolean
handle_trash_file (XdpTrash *object,
                   GDBusMethodInvocation *invocation,
                   GUnixFDList *fd_list,
                   GVariant *arg_fd)
{
  Request *request = request_from_invocation (invocation);
  int idx, fd;
  guint result;

  REQUEST_AUTOLOCK (request);

  g_variant_get (arg_fd, "h", &idx);
  fd = g_unix_fd_list_get (fd_list, idx, NULL);

  result = trash_file (request->app_info, request->sender, fd);

  xdp_trash_complete_trash_file (object, invocation, NULL, result);

  return TRUE;
}
static void
send_response_in_thread_func (GTask        *task,
                              gpointer      source_object,
                              gpointer      task_data,
                              GCancellable *cancellable)
{
  Request *request = task_data;
  GVariantBuilder results;
  GVariantBuilder ruris;
  guint response;
  GVariant *options;
  gboolean writable = TRUE;
  const char **uris;
  GVariant *choices;
  gboolean for_save;

  g_variant_builder_init (&results, G_VARIANT_TYPE_VARDICT);
  g_variant_builder_init (&ruris, G_VARIANT_TYPE_STRING_ARRAY);

  REQUEST_AUTOLOCK (request);

  for_save = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (request), "for-save"));
  response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (request), "response"));
  options = (GVariant *)g_object_get_data (G_OBJECT (request), "options");

  if (response != 0)
    goto out;

  if (!g_variant_lookup (options, "b", "writable", &writable))
    writable = FALSE;

  choices = g_variant_lookup_value (options, "choices", G_VARIANT_TYPE ("a(ss)"));
  if (choices)
    g_variant_builder_add (&results, "{sv}", "choices", choices);

  if (g_variant_lookup (options, "uris", "^a&s", &uris))
    {
      int i;

      for (i = 0; uris && uris[i]; i++)
        {
          g_autofree char *ruri = NULL;
          g_autoptr(GError) error = NULL;

          ruri = register_document (uris[i], request->app_id, for_save, writable, &error);
          if (ruri == NULL)
            {
              g_warning ("Failed to register %s: %s", uris[i], error->message);
              continue;
            }
          g_debug ("convert uri %s -> %s\n", uris[i], ruri);
          g_variant_builder_add (&ruris, "s", ruri);
        }
    }

out:
  g_variant_builder_add (&results, "{sv}", "uris", g_variant_builder_end (&ruris));

  if (request->exported)
    {
      xdp_request_emit_response (XDP_REQUEST (request),
                                 response,
                                 g_variant_builder_end (&results));
      request_unexport (request);
    }
}
static gboolean
handle_open_file (XdpFileChooser *object,
                  GDBusMethodInvocation *invocation,
                  const gchar *arg_parent_window,
                  const gchar *arg_title,
                  GVariant *arg_options)
{
  Request *request = request_from_invocation (invocation);
  const char *app_id = request->app_id;
  g_autoptr(GError) error = NULL;
  g_autoptr(XdpImplRequest) impl_request = NULL;
  GVariantBuilder options;
  g_autoptr(GVariant) value = NULL;

  REQUEST_AUTOLOCK (request);

  value = g_variant_lookup_value (arg_options, "filters", NULL);
  if (value != NULL)
    {
      if (!check_filters (value, &error))
        {
          g_prefix_error (&error, "invalid filters: ");
          g_dbus_method_invocation_return_gerror (invocation, error);
          return TRUE;
        }
      g_variant_unref (value);
      value = NULL;
    }
  value = g_variant_lookup_value (arg_options, "choices", NULL);
  if (value != NULL)
    {
      if (!check_choices (value, &error))
        {
          g_prefix_error (&error, "invalid choices: ");
          g_dbus_method_invocation_return_gerror (invocation, error);
          return TRUE;
        }
      g_variant_unref (value);
      value = NULL;
    }

  g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
  xdp_filter_options (arg_options, &options,
                      open_file_options, G_N_ELEMENTS (open_file_options));

  impl_request = xdp_impl_request_proxy_new_sync (g_dbus_proxy_get_connection (G_DBUS_PROXY (impl)),
                                                  G_DBUS_PROXY_FLAGS_NONE,
                                                  g_dbus_proxy_get_name (G_DBUS_PROXY (impl)),
                                                  request->id,
                                                  NULL, &error);
  if (!impl_request)
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      return TRUE;
    }

  request_set_impl_request (request, impl_request);
  request_export (request, g_dbus_method_invocation_get_connection (invocation));

  xdp_impl_file_chooser_call_open_file (impl,
                                        request->id,
                                        app_id,
                                        arg_parent_window,
                                        arg_title,
                                        g_variant_builder_end (&options),
                                        NULL,
                                        open_file_done,
                                        g_object_ref (request));

  xdp_file_chooser_complete_open_file (object, invocation, request->id);

  return TRUE;
}