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_screenshot (XdpImplScreenshot *object, GDBusMethodInvocation *invocation, const char *arg_handle, const char *arg_app_id, const char *arg_parent_window, GVariant *arg_options) { g_autoptr(Request) request = NULL; const char *sender; ScreenshotDialogHandle *handle; g_autoptr(GError) error = NULL; g_autofree char *filename = NULL; gboolean success; gboolean modal; GtkWidget *dialog; GdkDisplay *display; GdkScreen *screen; ExternalWindow *external_parent = NULL; GtkWidget *fake_parent; sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle); org_gnome_shell_screenshot_call_screenshot_sync (shell, FALSE, TRUE, "Screenshot", &success, &filename, NULL, NULL); if (!g_variant_lookup (arg_options, "modal", "b", &modal)) modal = TRUE; if (arg_parent_window) { external_parent = create_external_window_from_handle (arg_parent_window); if (!external_parent) g_warning ("Failed to associate portal window with parent window %s", arg_parent_window); } if (external_parent) display = external_window_get_display (external_parent); else display = gdk_display_get_default (); screen = gdk_display_get_default_screen (display); fake_parent = g_object_new (GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, "screen", screen, NULL); g_object_ref_sink (fake_parent); dialog = GTK_WIDGET (screenshot_dialog_new (arg_app_id, filename)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); gtk_window_set_modal (GTK_WINDOW (dialog), modal); handle = g_new0 (ScreenshotDialogHandle, 1); handle->impl = object; handle->invocation = invocation; handle->request = g_object_ref (request); handle->dialog = g_object_ref (dialog); handle->external_parent = external_parent; handle->uri = g_filename_to_uri (filename, NULL, NULL); g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); g_signal_connect (dialog, "done", G_CALLBACK (screenshot_dialog_done), handle); gtk_widget_realize (dialog); if (external_parent) external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog)); gtk_widget_show (dialog); request_export (request, g_dbus_method_invocation_get_connection (invocation)); return TRUE; }
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; }
static gboolean handle_access_dialog (XdpImplAccess *object, GDBusMethodInvocation *invocation, const char *arg_handle, const char *arg_app_id, const char *arg_parent_window, const char *arg_title, const char *arg_subtitle, const char *arg_body, GVariant *arg_options) { g_autoptr(Request) request = NULL; const char *sender; AccessDialogHandle *handle; g_autoptr(GError) error = NULL; g_autofree char *filename = NULL; gboolean modal; GtkWidget *dialog; GdkWindow *foreign_parent = NULL; const char *deny_label; const char *grant_label; const char *icon; g_autoptr(GVariant) choices = NULL; GtkWidget *area; GtkWidget *image; GHashTable *choice_table = NULL; sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle); if (!g_variant_lookup (arg_options, "modal", "b", &modal)) modal = TRUE; if (!g_variant_lookup (arg_options, "deny_label", "&s", &deny_label)) deny_label = _("Deny Access"); if (!g_variant_lookup (arg_options, "grant_label", "&s", &grant_label)) grant_label = _("Grant Access"); if (!g_variant_lookup (arg_options, "icon", "&s", &icon)) icon = NULL; choices = g_variant_lookup_value (arg_options, "choices", G_VARIANT_TYPE ("a(ssa(ss)s)")); dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, arg_title, NULL); gtk_window_set_modal (GTK_WINDOW (dialog), modal); gtk_dialog_add_button (GTK_DIALOG (dialog), deny_label, GTK_RESPONSE_CANCEL); gtk_dialog_add_button (GTK_DIALOG (dialog), grant_label, GTK_RESPONSE_OK); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", arg_subtitle); area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog)); fix_up_label_alignment (area); if (choices) { int i; choice_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < g_variant_n_children (choices); i++) add_choice (area, g_variant_get_child_value (choices, i), choice_table); } if (!g_str_equal (arg_body, "")) { GtkWidget *body_label; body_label = gtk_label_new (arg_body); gtk_widget_set_halign (body_label, GTK_ALIGN_START); g_object_set (body_label, "margin-top", 10, NULL); gtk_label_set_xalign (GTK_LABEL (body_label), 0); gtk_label_set_line_wrap (GTK_LABEL (body_label), TRUE); gtk_label_set_max_width_chars (GTK_LABEL (body_label), 50); gtk_widget_show (body_label); gtk_container_add (GTK_CONTAINER (area), body_label); } image = gtk_image_new_from_icon_name (icon ? icon : "image-missing", GTK_ICON_SIZE_DIALOG); gtk_widget_set_opacity (image, icon ? 1.0 : 0.0); gtk_widget_show (image); G_GNUC_BEGIN_IGNORE_DEPRECATIONS gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image); G_GNUC_END_IGNORE_DEPRECATIONS #ifdef GDK_WINDOWING_X11 if (g_str_has_prefix (arg_parent_window, "x11:")) { int xid; if (sscanf (arg_parent_window, "x11:%x", &xid) != 1) g_warning ("invalid xid"); else foreign_parent = gdk_x11_window_foreign_new_for_display (gtk_widget_get_display (dialog), xid); } #endif else g_warning ("Unhandled parent window type %s", arg_parent_window); handle = g_new0 (AccessDialogHandle, 1); handle->impl = object; handle->invocation = invocation; handle->request = g_object_ref (request); handle->dialog = g_object_ref (dialog); handle->choices = choice_table; g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); g_signal_connect (dialog, "response", G_CALLBACK (access_dialog_response), handle); gtk_widget_realize (dialog); if (foreign_parent) gdk_window_set_transient_for (gtk_widget_get_window (dialog), foreign_parent); gtk_widget_show (dialog); request_export (request, g_dbus_method_invocation_get_connection (invocation)); return TRUE; }
static gboolean handle_choose_application (XdpImplAppChooser *object, GDBusMethodInvocation *invocation, const char *arg_handle, const char *arg_app_id, const char *arg_parent_window, const char **choices, GVariant *arg_options) { g_autoptr(Request) request = NULL; GtkWidget *dialog; AppDialogHandle *handle; const char *sender; const char *latest_chosen_id; const char *content_type; const char *location; gboolean modal; GdkDisplay *display; GdkScreen *screen; ExternalWindow *external_parent = NULL; GtkWidget *fake_parent; sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle); if (!g_variant_lookup (arg_options, "last_choice", "&s", &latest_chosen_id)) latest_chosen_id = NULL; if (!g_variant_lookup (arg_options, "modal", "b", &modal)) modal = TRUE; if (!g_variant_lookup (arg_options, "content_type", "&s", &content_type)) content_type = NULL; if (!g_variant_lookup (arg_options, "filename", "&s", &location) && !g_variant_lookup (arg_options, "uri", "&s", &location)) location = NULL; if (arg_parent_window) { external_parent = create_external_window_from_handle (arg_parent_window); if (!external_parent) g_warning ("Failed to associate portal window with parent window %s", arg_parent_window); } if (external_parent) display = external_window_get_display (external_parent); else display = gdk_display_get_default (); screen = gdk_display_get_default_screen (display); fake_parent = g_object_new (GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, "screen", screen, NULL); g_object_ref_sink (fake_parent); dialog = GTK_WIDGET (app_chooser_dialog_new (choices, latest_chosen_id, content_type, location)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); gtk_window_set_modal (GTK_WINDOW (dialog), modal); handle = g_new0 (AppDialogHandle, 1); handle->impl = object; handle->invocation = invocation; handle->request = g_object_ref (request); handle->dialog = g_object_ref (dialog); handle->external_parent = external_parent; g_hash_table_insert (handles, handle->request->id, handle); g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); g_signal_connect (dialog, "close", G_CALLBACK (handle_app_chooser_close), handle); gtk_widget_realize (dialog); if (external_parent) external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog)); gtk_window_present (GTK_WINDOW (dialog)); request_export (request, g_dbus_method_invocation_get_connection (invocation)); return TRUE; }
static gboolean handle_get_user_information (XdpImplAccount *object, GDBusMethodInvocation *invocation, const char *arg_handle, const char *arg_app_id, const char *arg_parent_window, GVariant *arg_options) { g_autoptr(Request) request = NULL; const char *sender; AccountDialogHandle *handle; g_autoptr(GError) error = NULL; const char *user_name; const char *real_name; const char *icon_file; GtkWidget *dialog; GdkDisplay *display; GdkScreen *screen; ExternalWindow *external_parent = NULL; GtkWidget *fake_parent; const char *reason; sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle); user_name = org_freedesktop_accounts_user_get_user_name (user); real_name = org_freedesktop_accounts_user_get_real_name (user); icon_file = org_freedesktop_accounts_user_get_icon_file (user); if (!g_variant_lookup (arg_options, "reason", "&s", &reason)) reason = NULL; if (arg_parent_window) { external_parent = create_external_window_from_handle (arg_parent_window); if (!external_parent) g_warning ("Failed to associate portal window with parent window %s", arg_parent_window); } if (external_parent) display = external_window_get_display (external_parent); else display = gdk_display_get_default (); screen = gdk_display_get_default_screen (display); fake_parent = g_object_new (GTK_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, "screen", screen, NULL); g_object_ref_sink (fake_parent); dialog = GTK_WIDGET (account_dialog_new (arg_app_id, user_name, real_name, icon_file, reason)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); handle = g_new0 (AccountDialogHandle, 1); handle->impl = object; handle->invocation = invocation; handle->request = g_object_ref (request); handle->dialog = g_object_ref (dialog); handle->external_parent = external_parent; handle->user_name = g_strdup (user_name); handle->real_name = g_strdup (real_name); handle->icon_uri = g_filename_to_uri (icon_file, NULL, NULL); g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); g_signal_connect (dialog, "done", G_CALLBACK (account_dialog_done), handle); gtk_widget_realize (dialog); if (external_parent) external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog)); gtk_widget_show (dialog); request_export (request, g_dbus_method_invocation_get_connection (invocation)); return TRUE; }