/* GTK - The GIMP Toolkit
- * gtkprintoperation-unix.c: Print Operation Details for Unix and Unix like platforms
+ * gtkprintoperation-unix.c: Print Operation Details for Unix
+ * and Unix-like platforms
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
#include <cairo-pdf.h>
#include <cairo-ps.h>
+#include "gtkprivate.h"
#include "gtkprintunixdialog.h"
#include "gtkpagesetupunixdialog.h"
#include "gtkprintbackend.h"
#include "gtkprinter.h"
+#include "gtkprinter-private.h"
#include "gtkprintjob.h"
#include "gtklabel.h"
#include "gtkalias.h"
return result;
}
+static void
+gtk_print_operation_unix_initialize (void)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized)
+ {
+ /**
+ * GtkSettings:gtk-print-preview-command:
+ *
+ * A command to run for displaying the print preview. The command
+ * should contain a %f placeholder, which will get replaced by
+ * the path to the pdf file.
+ *
+ * The preview application is responsible for removing the pdf file
+ * when it is done.
+ *
+ * Since: 2.10
+ */
+ gtk_settings_install_property (g_param_spec_string ("gtk-print-preview-command",
+ P_("Default command to run when displaying a print preview"),
+ P_("Command to run when displaying a print preview"),
+ GTK_PRINT_PREVIEW_COMMAND,
+ GTK_PARAM_READWRITE));
+ initialized = TRUE;
+ }
+}
+
void
_gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
cairo_surface_t *surface,
GdkScreen *screen;
GError *error = NULL;
+ gtk_print_operation_unix_initialize ();
+
cairo_surface_destroy (surface);
settings = gtk_settings_get_default ();
if (op_unix->job != NULL)
gtk_print_job_send (op_unix->job,
unix_finish_send,
- op_unix, NULL,
- NULL);
+ op_unix, NULL);
if (wait)
{
GTK_PRINT_CAPABILITY_COPIES |
GTK_PRINT_CAPABILITY_COLLATE |
GTK_PRINT_CAPABILITY_REVERSE |
- GTK_PRINT_CAPABILITY_SCALE);
+ GTK_PRINT_CAPABILITY_SCALE |
+ GTK_PRINT_CAPABILITY_GENERATE_PDF |
+ GTK_PRINT_CAPABILITY_GENERATE_PS |
+ GTK_PRINT_CAPABILITY_PREVIEW);
if (priv->print_settings)
gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd),
rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
rdata->do_preview = TRUE;
rdata->do_print = TRUE;
+
+ rdata->op->priv->action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
}
if (rdata->do_print)
}
}
+static cairo_status_t
+write_preview (void *closure,
+ const unsigned char *data,
+ unsigned int length)
+{
+ gint fd = GPOINTER_TO_INT (closure);
+ gssize written;
+
+ while (length > 0)
+ {
+ written = write (fd, data, length);
+
+ if (written == -1)
+ {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+
+ return CAIRO_STATUS_WRITE_ERROR;
+ }
+
+ data += written;
+ length -= written;
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+close_preview (void *data)
+{
+ gint fd = GPOINTER_TO_INT (data);
+
+ close (fd);
+}
+
cairo_surface_t *
_gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
GtkPageSetup *page_setup,
gdouble *dpi_y,
gchar **target)
{
- gchar *tmp_dir, *dir_template, *preview_filename;
+ gchar *filename;
+ gint fd;
GtkPaperSize *paper_size;
gdouble w, h;
+ cairo_surface_t *surface;
+ static cairo_user_data_key_t key;
- dir_template = g_build_filename (g_get_tmp_dir (), "print-preview-XXXXXX", NULL);
-
- /* use temp dirs because apps like evince need to have extensions
- * to determine the mime type
- */
- tmp_dir = mkdtemp(dir_template);
- preview_filename = g_build_filename (tmp_dir,
- "Print Preview.pdf",
- NULL);
- g_free (dir_template);
- *target = preview_filename;
+ filename = g_build_filename (g_get_tmp_dir (), "previewXXXXXX.pdf", NULL);
+ fd = g_mkstemp (filename);
+ *target = filename;
+ g_print ("target is %s\n", filename);
+
paper_size = gtk_page_setup_get_paper_size (page_setup);
w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
*dpi_x = *dpi_y = 72;
- return cairo_pdf_surface_create (preview_filename, w, h);
+ surface = cairo_pdf_surface_create_for_stream (write_preview, GINT_TO_POINTER(fd), w, h);
+
+ cairo_surface_set_user_data (surface, &key, GINT_TO_POINTER (fd), close_preview);
+
+ return surface;
}
void
{
PageSetupResponseData *rdata = data;
- g_object_unref (rdata->page_setup);
+ if (rdata->page_setup)
+ g_object_unref (rdata->page_setup);
+
g_free (rdata);
}