1 /* GTK - The GIMP Toolkit
2 * gtkprintoperation-unix.c: Print Operation Details for Unix
3 * and Unix-like platforms
4 * Copyright (C) 2006, Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
26 #include <sys/types.h>
33 #include <glib/gstdio.h>
34 #include "gtkprintoperation-private.h"
35 #include "gtkmessagedialog.h"
37 #include <cairo-pdf.h>
39 #include "gtkprivate.h"
40 #include "gtkprintunixdialog.h"
41 #include "gtkpagesetupunixdialog.h"
42 #include "gtkprintbackend.h"
43 #include "gtkprinter.h"
44 #include "gtkprinter-private.h"
45 #include "gtkprintjob.h"
52 GtkWindow *parent; /* just in case we need to throw error dialogs */
56 /* Real printing (not preview) */
57 GtkPrintJob *job; /* the job we are sending to the printer */
58 cairo_surface_t *surface;
59 gulong job_status_changed_tag;
62 } GtkPrintOperationUnix;
64 typedef struct _PrinterFinder PrinterFinder;
66 static void printer_finder_free (PrinterFinder *finder);
67 static void find_printer (const gchar *printer,
72 unix_start_page (GtkPrintOperation *op,
73 GtkPrintContext *print_context,
74 GtkPageSetup *page_setup)
76 GtkPrintOperationUnix *op_unix;
77 GtkPaperSize *paper_size;
78 cairo_surface_type_t type;
81 op_unix = op->priv->platform_data;
83 paper_size = gtk_page_setup_get_paper_size (page_setup);
85 w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
86 h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
88 type = cairo_surface_get_type (op_unix->surface);
90 if ((op->priv->manual_number_up < 2) ||
91 (op->priv->page_position % op->priv->manual_number_up == 0))
93 if (type == CAIRO_SURFACE_TYPE_PS)
95 cairo_ps_surface_set_size (op_unix->surface, w, h);
96 cairo_ps_surface_dsc_begin_page_setup (op_unix->surface);
97 switch (gtk_page_setup_get_orientation (page_setup))
99 case GTK_PAGE_ORIENTATION_PORTRAIT:
100 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
101 cairo_ps_surface_dsc_comment (op_unix->surface, "%%PageOrientation: Portrait");
104 case GTK_PAGE_ORIENTATION_LANDSCAPE:
105 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
106 cairo_ps_surface_dsc_comment (op_unix->surface, "%%PageOrientation: Landscape");
110 else if (type == CAIRO_SURFACE_TYPE_PDF)
112 cairo_pdf_surface_set_size (op_unix->surface, w, h);
118 unix_end_page (GtkPrintOperation *op,
119 GtkPrintContext *print_context)
123 cr = gtk_print_context_get_cairo_context (print_context);
125 if ((op->priv->manual_number_up < 2) ||
126 ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
127 (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
128 cairo_show_page (cr);
132 op_unix_free (GtkPrintOperationUnix *op_unix)
136 g_signal_handler_disconnect (op_unix->job,
137 op_unix->job_status_changed_tag);
138 g_object_unref (op_unix->job);
145 shell_command_substitute_file (const gchar *cmd,
146 const gchar *pdf_filename,
147 const gchar *settings_filename,
148 gboolean *pdf_filename_replaced,
149 gboolean *settings_filename_replaced)
151 const gchar *inptr, *start;
154 g_return_val_if_fail (cmd != NULL, NULL);
155 g_return_val_if_fail (pdf_filename != NULL, NULL);
156 g_return_val_if_fail (settings_filename != NULL, NULL);
158 final = g_string_new (NULL);
160 *pdf_filename_replaced = FALSE;
161 *settings_filename_replaced = FALSE;
164 while ((inptr = strchr (inptr, '%')) != NULL)
166 g_string_append_len (final, start, inptr - start);
171 g_string_append (final, pdf_filename);
172 *pdf_filename_replaced = TRUE;
176 g_string_append (final, settings_filename);
177 *settings_filename_replaced = TRUE;
181 g_string_append_c (final, '%');
185 g_string_append_c (final, '%');
187 g_string_append_c (final, *inptr);
194 g_string_append (final, start);
196 return g_string_free (final, FALSE);
200 _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
201 cairo_surface_t *surface,
203 const gchar *filename)
209 GtkSettings *settings;
210 GtkPrintSettings *print_settings = NULL;
211 GtkPageSetup *page_setup;
212 GKeyFile *key_file = NULL;
215 gchar *settings_filename = NULL;
216 gchar *quoted_filename;
217 gchar *quoted_settings_filename;
218 gboolean filename_used = FALSE;
219 gboolean settings_used = FALSE;
221 GError *error = NULL;
225 cairo_surface_destroy (surface);
228 screen = gtk_window_get_screen (parent);
230 screen = gdk_screen_get_default ();
232 fd = g_file_open_tmp ("settingsXXXXXX.ini", &settings_filename, &error);
236 key_file = g_key_file_new ();
238 print_settings = gtk_print_settings_copy (gtk_print_operation_get_print_settings (op));
240 if (print_settings != NULL)
242 gtk_print_settings_set_reverse (print_settings, FALSE);
243 gtk_print_settings_set_page_set (print_settings, GTK_PAGE_SET_ALL);
244 gtk_print_settings_set_scale (print_settings, 1.0);
245 gtk_print_settings_set_number_up (print_settings, 1);
246 gtk_print_settings_set_number_up_layout (print_settings, GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM);
248 /* These removals are neccessary because cups-* settings have higher priority
249 * than normal settings.
251 gtk_print_settings_unset (print_settings, "cups-reverse");
252 gtk_print_settings_unset (print_settings, "cups-page-set");
253 gtk_print_settings_unset (print_settings, "cups-scale");
254 gtk_print_settings_unset (print_settings, "cups-number-up");
255 gtk_print_settings_unset (print_settings, "cups-number-up-layout");
257 gtk_print_settings_to_key_file (print_settings, key_file, NULL);
258 g_object_unref (print_settings);
261 page_setup = gtk_print_context_get_page_setup (op->priv->print_context);
262 gtk_page_setup_to_key_file (page_setup, key_file, NULL);
264 g_key_file_set_string (key_file, "Print Job", "title", op->priv->job_name);
266 data = g_key_file_to_data (key_file, &data_len, &error);
270 retval = g_file_set_contents (settings_filename, data, data_len, &error);
274 settings = gtk_settings_get_for_screen (screen);
275 g_object_get (settings, "gtk-print-preview-command", &preview_cmd, NULL);
277 quoted_filename = g_shell_quote (filename);
278 quoted_settings_filename = g_shell_quote (settings_filename);
279 cmd = shell_command_substitute_file (preview_cmd, quoted_filename, quoted_settings_filename, &filename_used, &settings_used);
280 g_shell_parse_argv (cmd, &argc, &argv, &error);
282 g_free (preview_cmd);
283 g_free (quoted_filename);
284 g_free (quoted_settings_filename);
290 gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
298 edialog = gtk_message_dialog_new (parent,
299 GTK_DIALOG_DESTROY_WITH_PARENT,
302 _("Error launching preview") /* FIXME better text */);
303 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog),
304 "%s", error->message);
305 g_signal_connect (edialog, "response",
306 G_CALLBACK (gtk_widget_destroy), NULL);
308 gtk_window_present (GTK_WINDOW (edialog));
310 g_error_free (error);
312 filename_used = FALSE;
313 settings_used = FALSE;
320 g_unlink (settings_filename);
326 g_key_file_free (key_file);
328 g_free (settings_filename);
332 unix_finish_send (GtkPrintJob *job,
336 GtkPrintOperation *op = (GtkPrintOperation *) user_data;
337 GtkPrintOperationUnix *op_unix = op->priv->platform_data;
342 edialog = gtk_message_dialog_new (op_unix->parent,
343 GTK_DIALOG_DESTROY_WITH_PARENT,
346 _("Error printing") /* FIXME better text */);
347 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog),
348 "%s", error->message);
349 gtk_window_set_modal (GTK_WINDOW (edialog), TRUE);
350 g_signal_connect (edialog, "response",
351 G_CALLBACK (gtk_widget_destroy), NULL);
353 gtk_window_present (GTK_WINDOW (edialog));
356 op_unix->data_sent = TRUE;
359 g_main_loop_quit (op_unix->loop);
365 unix_end_run (GtkPrintOperation *op,
369 GtkPrintOperationUnix *op_unix = op->priv->platform_data;
371 cairo_surface_finish (op_unix->surface);
377 op_unix->loop = g_main_loop_new (NULL, FALSE);
379 /* TODO: Check for error */
380 if (op_unix->job != NULL)
383 gtk_print_job_send (op_unix->job,
391 if (!op_unix->data_sent)
393 GDK_THREADS_LEAVE ();
394 g_main_loop_run (op_unix->loop);
395 GDK_THREADS_ENTER ();
397 g_main_loop_unref (op_unix->loop);
398 op_unix->loop = NULL;
404 job_status_changed_cb (GtkPrintJob *job,
405 GtkPrintOperation *op)
407 _gtk_print_operation_set_status (op, gtk_print_job_get_status (job), NULL);
412 print_setup_changed_cb (GtkPrintUnixDialog *print_dialog,
416 GtkPageSetup *page_setup;
417 GtkPrintSettings *print_settings;
418 GtkPrintOperation *op = user_data;
419 GtkPrintOperationPrivate *priv = op->priv;
421 page_setup = gtk_print_unix_dialog_get_page_setup (print_dialog);
422 print_settings = gtk_print_unix_dialog_get_settings (print_dialog);
424 g_signal_emit_by_name (op,
425 "update-custom-widget",
432 get_print_dialog (GtkPrintOperation *op,
435 GtkPrintOperationPrivate *priv = op->priv;
436 GtkWidget *pd, *label;
437 const gchar *custom_tab_label;
439 pd = gtk_print_unix_dialog_new (NULL, parent);
441 gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (pd),
442 GTK_PRINT_CAPABILITY_PAGE_SET |
443 GTK_PRINT_CAPABILITY_COPIES |
444 GTK_PRINT_CAPABILITY_COLLATE |
445 GTK_PRINT_CAPABILITY_REVERSE |
446 GTK_PRINT_CAPABILITY_SCALE |
447 GTK_PRINT_CAPABILITY_PREVIEW |
448 GTK_PRINT_CAPABILITY_NUMBER_UP |
449 GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT);
451 if (priv->print_settings)
452 gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd),
453 priv->print_settings);
455 if (priv->default_page_setup)
456 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd),
457 priv->default_page_setup);
459 gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (pd),
460 priv->embed_page_setup);
462 gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd),
465 gtk_print_unix_dialog_set_support_selection (GTK_PRINT_UNIX_DIALOG (pd),
466 priv->support_selection);
468 gtk_print_unix_dialog_set_has_selection (GTK_PRINT_UNIX_DIALOG (pd),
469 priv->has_selection);
471 g_signal_emit_by_name (op, "create-custom-widget",
472 &priv->custom_widget);
474 if (priv->custom_widget)
476 custom_tab_label = priv->custom_tab_label;
478 if (custom_tab_label == NULL)
480 custom_tab_label = g_get_application_name ();
481 if (custom_tab_label == NULL)
482 custom_tab_label = _("Application");
485 label = gtk_label_new (custom_tab_label);
487 gtk_print_unix_dialog_add_custom_tab (GTK_PRINT_UNIX_DIALOG (pd),
488 priv->custom_widget, label);
490 g_signal_connect (pd, "notify::selected-printer", (GCallback) print_setup_changed_cb, op);
491 g_signal_connect (pd, "notify::page-setup", (GCallback) print_setup_changed_cb, op);
499 GtkPrintOperation *op;
502 GtkPrintOperationResult result;
503 GtkPrintOperationPrintFunc print_cb;
504 GDestroyNotify destroy;
510 print_response_data_free (gpointer data)
512 PrintResponseData *rdata = data;
514 g_object_unref (rdata->op);
519 finish_print (PrintResponseData *rdata,
521 GtkPageSetup *page_setup,
522 GtkPrintSettings *settings,
523 gboolean page_setup_set)
525 GtkPrintOperation *op = rdata->op;
526 GtkPrintOperationPrivate *priv = op->priv;
531 gtk_print_operation_set_print_settings (op, settings);
532 priv->print_context = _gtk_print_context_new (op);
534 if (page_setup != NULL &&
535 (gtk_print_operation_get_default_page_setup (op) == NULL ||
537 gtk_print_operation_set_default_page_setup (op, page_setup);
539 _gtk_print_context_set_page_setup (priv->print_context, page_setup);
541 if (!rdata->do_preview)
543 GtkPrintOperationUnix *op_unix;
546 op_unix = g_new0 (GtkPrintOperationUnix, 1);
547 priv->platform_data = op_unix;
548 priv->free_platform_data = (GDestroyNotify) op_unix_free;
549 op_unix->parent = rdata->parent;
551 priv->start_page = unix_start_page;
552 priv->end_page = unix_end_page;
553 priv->end_run = unix_end_run;
555 job = gtk_print_job_new (priv->job_name, printer, settings, page_setup);
557 gtk_print_job_set_track_print_status (job, priv->track_print_status);
559 op_unix->surface = gtk_print_job_get_surface (job, &priv->error);
560 if (op_unix->surface == NULL)
562 rdata->result = GTK_PRINT_OPERATION_RESULT_ERROR;
563 rdata->do_print = FALSE;
567 cr = cairo_create (op_unix->surface);
568 gtk_print_context_set_cairo_context (priv->print_context, cr, 72, 72);
571 _gtk_print_operation_set_status (op, gtk_print_job_get_status (job), NULL);
573 op_unix->job_status_changed_tag =
574 g_signal_connect (job, "status-changed",
575 G_CALLBACK (job_status_changed_cb), op);
577 priv->print_pages = job->print_pages;
578 priv->page_ranges = job->page_ranges;
579 priv->num_page_ranges = job->num_page_ranges;
581 priv->manual_num_copies = job->num_copies;
582 priv->manual_collation = job->collate;
583 priv->manual_reverse = job->reverse;
584 priv->manual_page_set = job->page_set;
585 priv->manual_scale = job->scale;
586 priv->manual_orientation = job->rotate_to_orientation;
587 priv->manual_number_up = job->number_up;
588 priv->manual_number_up_layout = job->number_up_layout;
593 rdata->print_cb (op, rdata->parent, rdata->do_print, rdata->result);
596 rdata->destroy (rdata);
600 handle_print_response (GtkWidget *dialog,
604 GtkPrintUnixDialog *pd = GTK_PRINT_UNIX_DIALOG (dialog);
605 PrintResponseData *rdata = data;
606 GtkPrintSettings *settings = NULL;
607 GtkPageSetup *page_setup = NULL;
608 GtkPrinter *printer = NULL;
609 gboolean page_setup_set = FALSE;
611 if (response == GTK_RESPONSE_OK)
613 printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (pd));
615 rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
616 rdata->do_preview = FALSE;
618 rdata->do_print = TRUE;
620 else if (response == GTK_RESPONSE_APPLY)
623 rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
624 rdata->do_preview = TRUE;
625 rdata->do_print = TRUE;
627 rdata->op->priv->action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
632 settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd));
633 page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd));
634 page_setup_set = gtk_print_unix_dialog_get_page_setup_set (GTK_PRINT_UNIX_DIALOG (pd));
636 g_signal_emit_by_name (rdata->op, "custom-widget-apply", rdata->op->priv->custom_widget);
639 finish_print (rdata, printer, page_setup, settings, page_setup_set);
642 g_object_unref (settings);
644 gtk_widget_destroy (GTK_WIDGET (pd));
650 found_printer (GtkPrinter *printer,
651 PrintResponseData *rdata)
653 GtkPrintOperation *op = rdata->op;
654 GtkPrintOperationPrivate *priv = op->priv;
655 GtkPrintSettings *settings = NULL;
656 GtkPageSetup *page_setup = NULL;
659 g_main_loop_quit (rdata->loop);
663 rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
665 rdata->do_print = TRUE;
667 if (priv->print_settings)
668 settings = gtk_print_settings_copy (priv->print_settings);
670 settings = gtk_print_settings_new ();
672 gtk_print_settings_set_printer (settings,
673 gtk_printer_get_name (printer));
675 if (priv->default_page_setup)
676 page_setup = gtk_page_setup_copy (priv->default_page_setup);
678 page_setup = gtk_page_setup_new ();
681 finish_print (rdata, printer, page_setup, settings, FALSE);
684 g_object_unref (settings);
687 g_object_unref (page_setup);
691 _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
692 gboolean show_dialog,
694 GtkPrintOperationPrintFunc print_cb)
697 PrintResponseData *rdata;
698 const gchar *printer_name;
700 rdata = g_new (PrintResponseData, 1);
701 rdata->op = g_object_ref (op);
702 rdata->do_print = FALSE;
703 rdata->do_preview = FALSE;
704 rdata->result = GTK_PRINT_OPERATION_RESULT_CANCEL;
705 rdata->print_cb = print_cb;
706 rdata->parent = parent;
708 rdata->destroy = print_response_data_free;
712 pd = get_print_dialog (op, parent);
713 gtk_window_set_modal (GTK_WINDOW (pd), TRUE);
715 g_signal_connect (pd, "response",
716 G_CALLBACK (handle_print_response), rdata);
718 gtk_window_present (GTK_WINDOW (pd));
723 if (op->priv->print_settings)
724 printer_name = gtk_print_settings_get_printer (op->priv->print_settings);
726 find_printer (printer_name, (GFunc) found_printer, rdata);
730 static cairo_status_t
731 write_preview (void *closure,
732 const unsigned char *data,
735 gint fd = GPOINTER_TO_INT (closure);
740 written = write (fd, data, length);
744 if (errno == EAGAIN || errno == EINTR)
747 return CAIRO_STATUS_WRITE_ERROR;
754 return CAIRO_STATUS_SUCCESS;
758 close_preview (void *data)
760 gint fd = GPOINTER_TO_INT (data);
766 _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
767 GtkPageSetup *page_setup,
774 GtkPaperSize *paper_size;
776 cairo_surface_t *surface;
777 static cairo_user_data_key_t key;
779 filename = g_build_filename (g_get_tmp_dir (), "previewXXXXXX.pdf", NULL);
780 fd = g_mkstemp (filename);
790 paper_size = gtk_page_setup_get_paper_size (page_setup);
791 w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
792 h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
794 *dpi_x = *dpi_y = 72;
795 surface = cairo_pdf_surface_create_for_stream (write_preview, GINT_TO_POINTER (fd), w, h);
797 cairo_surface_set_user_data (surface, &key, GINT_TO_POINTER (fd), close_preview);
803 _gtk_print_operation_platform_backend_preview_start_page (GtkPrintOperation *op,
804 cairo_surface_t *surface,
810 _gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op,
811 cairo_surface_t *surface,
814 cairo_show_page (cr);
818 _gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
819 GtkPageSetup *page_setup,
820 cairo_surface_t *surface)
822 GtkPaperSize *paper_size;
825 paper_size = gtk_page_setup_get_paper_size (page_setup);
826 w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
827 h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
828 cairo_pdf_surface_set_size (surface, w, h);
832 GtkPrintOperationResult
833 _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
834 gboolean show_dialog,
839 PrintResponseData rdata;
841 const gchar *printer_name;
844 rdata.do_print = FALSE;
845 rdata.do_preview = FALSE;
846 rdata.result = GTK_PRINT_OPERATION_RESULT_CANCEL;
847 rdata.print_cb = NULL;
848 rdata.destroy = NULL;
849 rdata.parent = parent;
854 pd = get_print_dialog (op, parent);
856 response = gtk_dialog_run (GTK_DIALOG (pd));
857 handle_print_response (pd, response, &rdata);
862 if (op->priv->print_settings)
863 printer_name = gtk_print_settings_get_printer (op->priv->print_settings);
865 rdata.loop = g_main_loop_new (NULL, FALSE);
866 find_printer (printer_name,
867 (GFunc) found_printer, &rdata);
869 GDK_THREADS_LEAVE ();
870 g_main_loop_run (rdata.loop);
871 GDK_THREADS_ENTER ();
873 g_main_loop_unref (rdata.loop);
877 *do_print = rdata.do_print;
885 GtkPageSetup *page_setup;
886 GtkPageSetupDoneFunc done_cb;
888 GDestroyNotify destroy;
889 } PageSetupResponseData;
892 page_setup_data_free (gpointer data)
894 PageSetupResponseData *rdata = data;
896 if (rdata->page_setup)
897 g_object_unref (rdata->page_setup);
903 handle_page_setup_response (GtkWidget *dialog,
907 GtkPageSetupUnixDialog *psd;
908 PageSetupResponseData *rdata = data;
910 psd = GTK_PAGE_SETUP_UNIX_DIALOG (dialog);
911 if (response == GTK_RESPONSE_OK)
912 rdata->page_setup = gtk_page_setup_unix_dialog_get_page_setup (psd);
914 gtk_widget_destroy (dialog);
917 rdata->done_cb (rdata->page_setup, rdata->data);
920 rdata->destroy (rdata);
924 get_page_setup_dialog (GtkWindow *parent,
925 GtkPageSetup *page_setup,
926 GtkPrintSettings *settings)
930 dialog = gtk_page_setup_unix_dialog_new (NULL, parent);
932 gtk_page_setup_unix_dialog_set_page_setup (GTK_PAGE_SETUP_UNIX_DIALOG (dialog),
934 gtk_page_setup_unix_dialog_set_print_settings (GTK_PAGE_SETUP_UNIX_DIALOG (dialog),
941 * gtk_print_run_page_setup_dialog:
942 * @parent: transient parent, or %NULL
943 * @page_setup: an existing #GtkPageSetup, or %NULL
944 * @settings: a #GtkPrintSettings
946 * Runs a page setup dialog, letting the user modify the values from
947 * @page_setup. If the user cancels the dialog, the returned #GtkPageSetup
948 * is identical to the passed in @page_setup, otherwise it contains the
949 * modifications done in the dialog.
951 * Note that this function may use a recursive mainloop to show the page
952 * setup dialog. See gtk_print_run_page_setup_dialog_async() if this is
955 * Return value: a new #GtkPageSetup
960 gtk_print_run_page_setup_dialog (GtkWindow *parent,
961 GtkPageSetup *page_setup,
962 GtkPrintSettings *settings)
966 PageSetupResponseData rdata;
968 rdata.page_setup = NULL;
969 rdata.done_cb = NULL;
971 rdata.destroy = NULL;
973 dialog = get_page_setup_dialog (parent, page_setup, settings);
974 response = gtk_dialog_run (GTK_DIALOG (dialog));
975 handle_page_setup_response (dialog, response, &rdata);
977 if (rdata.page_setup)
978 return rdata.page_setup;
980 return gtk_page_setup_copy (page_setup);
982 return gtk_page_setup_new ();
986 * gtk_print_run_page_setup_dialog_async:
987 * @parent: transient parent, or %NULL
988 * @page_setup: an existing #GtkPageSetup, or %NULL
989 * @settings: a #GtkPrintSettings
990 * @done_cb: a function to call when the user saves the modified page setup
991 * @data: user data to pass to @done_cb
993 * Runs a page setup dialog, letting the user modify the values from @page_setup.
995 * In contrast to gtk_print_run_page_setup_dialog(), this function returns after
996 * showing the page setup dialog on platforms that support this, and calls @done_cb
997 * from a signal handler for the ::response signal of the dialog.
1002 gtk_print_run_page_setup_dialog_async (GtkWindow *parent,
1003 GtkPageSetup *page_setup,
1004 GtkPrintSettings *settings,
1005 GtkPageSetupDoneFunc done_cb,
1009 PageSetupResponseData *rdata;
1011 dialog = get_page_setup_dialog (parent, page_setup, settings);
1012 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1014 rdata = g_new (PageSetupResponseData, 1);
1015 rdata->page_setup = NULL;
1016 rdata->done_cb = done_cb;
1018 rdata->destroy = page_setup_data_free;
1020 g_signal_connect (dialog, "response",
1021 G_CALLBACK (handle_page_setup_response), rdata);
1023 gtk_window_present (GTK_WINDOW (dialog));
1026 struct _PrinterFinder
1028 gboolean found_printer;
1031 gchar *printer_name;
1034 GtkPrinter *printer;
1035 GtkPrinter *default_printer;
1036 GtkPrinter *first_printer;
1040 find_printer_idle (gpointer data)
1042 PrinterFinder *finder = data;
1043 GtkPrinter *printer;
1045 if (finder->printer != NULL)
1046 printer = finder->printer;
1047 else if (finder->default_printer != NULL)
1048 printer = finder->default_printer;
1049 else if (finder->first_printer != NULL)
1050 printer = finder->first_printer;
1054 finder->func (printer, finder->data);
1056 printer_finder_free (finder);
1062 printer_added_cb (GtkPrintBackend *backend,
1063 GtkPrinter *printer,
1064 PrinterFinder *finder)
1066 if (finder->found_printer)
1069 /* FIXME this skips "Print to PDF" - is this intentional ? */
1070 if (gtk_printer_is_virtual (printer))
1073 if (finder->printer_name != NULL &&
1074 strcmp (gtk_printer_get_name (printer), finder->printer_name) == 0)
1076 finder->printer = g_object_ref (printer);
1077 finder->found_printer = TRUE;
1079 else if (finder->default_printer == NULL &&
1080 gtk_printer_is_default (printer))
1082 finder->default_printer = g_object_ref (printer);
1083 if (finder->printer_name == NULL)
1084 finder->found_printer = TRUE;
1087 if (finder->first_printer == NULL)
1088 finder->first_printer = g_object_ref (printer);
1090 if (finder->found_printer)
1091 g_idle_add (find_printer_idle, finder);
1095 printer_list_done_cb (GtkPrintBackend *backend,
1096 PrinterFinder *finder)
1098 finder->backends = g_list_remove (finder->backends, backend);
1100 g_signal_handlers_disconnect_by_func (backend, printer_added_cb, finder);
1101 g_signal_handlers_disconnect_by_func (backend, printer_list_done_cb, finder);
1103 gtk_print_backend_destroy (backend);
1104 g_object_unref (backend);
1106 if (finder->backends == NULL && !finder->found_printer)
1107 g_idle_add (find_printer_idle, finder);
1111 find_printer_init (PrinterFinder *finder,
1112 GtkPrintBackend *backend)
1117 list = gtk_print_backend_get_printer_list (backend);
1120 while (node != NULL)
1122 printer_added_cb (backend, node->data, finder);
1125 if (finder->found_printer)
1131 if (gtk_print_backend_printer_list_is_done (backend))
1133 finder->backends = g_list_remove (finder->backends, backend);
1134 gtk_print_backend_destroy (backend);
1135 g_object_unref (backend);
1139 g_signal_connect (backend, "printer-added",
1140 (GCallback) printer_added_cb,
1142 g_signal_connect (backend, "printer-list-done",
1143 (GCallback) printer_list_done_cb,
1150 printer_finder_free (PrinterFinder *finder)
1154 g_free (finder->printer_name);
1156 if (finder->printer)
1157 g_object_unref (finder->printer);
1159 if (finder->default_printer)
1160 g_object_unref (finder->default_printer);
1162 if (finder->first_printer)
1163 g_object_unref (finder->first_printer);
1165 for (l = finder->backends; l != NULL; l = l->next)
1167 GtkPrintBackend *backend = l->data;
1168 g_signal_handlers_disconnect_by_func (backend, printer_added_cb, finder);
1169 g_signal_handlers_disconnect_by_func (backend, printer_list_done_cb, finder);
1170 gtk_print_backend_destroy (backend);
1171 g_object_unref (backend);
1174 g_list_free (finder->backends);
1180 find_printer (const gchar *printer,
1185 PrinterFinder *finder;
1187 finder = g_new0 (PrinterFinder, 1);
1189 finder->printer_name = g_strdup (printer);
1190 finder->func = func;
1191 finder->data = data;
1193 finder->backends = NULL;
1194 if (g_module_supported ())
1195 finder->backends = gtk_print_backend_load_modules ();
1197 for (node = finder->backends; !finder->found_printer && node != NULL; node = next)
1200 find_printer_init (finder, GTK_PRINT_BACKEND (node->data));
1203 if (finder->backends == NULL && !finder->found_printer)
1204 g_idle_add (find_printer_idle, finder);
1207 #define __GTK_PRINT_OPERATION_UNIX_C__
1208 #include "gtkaliasdef.c"