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); } }
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; }
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); } }
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; }
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; }
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; }