]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkprintoperation-unix.c
(gtk_notebook_drag_motion): Don't accept drops on
[~andy/gtk] / gtk / gtkprintoperation-unix.c
index e73964076aac6e2932dd96dbd64a40584438473e..c5c71e82e71d68caf88bc44553512d2886127451 100644 (file)
@@ -1,5 +1,6 @@
 /* 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"
@@ -162,6 +165,34 @@ shell_command_substitute_file (const gchar *cmd,
   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,
@@ -177,6 +208,8 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
   GdkScreen *screen;
   GError *error = NULL;
 
+  gtk_print_operation_unix_initialize ();
+
   cairo_surface_destroy (surface);
  
   settings = gtk_settings_get_default ();
@@ -273,8 +306,7 @@ unix_end_run (GtkPrintOperation *op,
   if (op_unix->job != NULL)
     gtk_print_job_send (op_unix->job,
                         unix_finish_send, 
-                        op_unix, NULL,
-                       NULL);
+                        op_unix, NULL);
 
   if (wait)
     {
@@ -312,7 +344,10 @@ get_print_dialog (GtkPrintOperation *op,
                                                 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),
@@ -468,6 +503,8 @@ handle_print_response (GtkWidget *dialog,
       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)
@@ -568,6 +605,41 @@ _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation
     }
 }
 
+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,
@@ -575,28 +647,29 @@ _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation
                                                              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
@@ -692,7 +765,9 @@ page_setup_data_free (gpointer data)
 {
   PageSetupResponseData *rdata = data;
 
-  g_object_unref (rdata->page_setup);
+  if (rdata->page_setup)
+    g_object_unref (rdata->page_setup);
+
   g_free (rdata);
 }