+#endif /* GTKUNIXPRINT_ENABLED */
+
+#if GTK_CHECK_VERSION (2, 17, 1)
+/* Print to cairo interface */
+#define EV_TYPE_PRINT_OPERATION_PRINT (ev_print_operation_print_get_type())
+#define EV_PRINT_OPERATION_PRINT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrint))
+#define EV_PRINT_OPERATION_PRINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrintClass))
+#define EV_IS_PRINT_OPERATION_PRINT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PRINT_OPERATION_PRINT))
+
+typedef struct _EvPrintOperationPrint EvPrintOperationPrint;
+typedef struct _EvPrintOperationPrintClass EvPrintOperationPrintClass;
+
+static GType ev_print_operation_print_get_type (void) G_GNUC_CONST;
+
+struct _EvPrintOperationPrint {
+ EvPrintOperation parent;
+
+ GtkPrintOperation *op;
+ gint n_pages_to_print;
+ gint total;
+ EvJob *job_print;
+ gchar *job_name;
+};
+
+struct _EvPrintOperationPrintClass {
+ EvPrintOperationClass parent_class;
+};
+
+G_DEFINE_TYPE (EvPrintOperationPrint, ev_print_operation_print, EV_TYPE_PRINT_OPERATION)
+
+static void
+ev_print_operation_print_set_current_page (EvPrintOperation *op,
+ gint current_page)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ gtk_print_operation_set_current_page (print->op, current_page);
+}
+
+static void
+ev_print_operation_print_set_print_settings (EvPrintOperation *op,
+ GtkPrintSettings *print_settings)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ gtk_print_operation_set_print_settings (print->op, print_settings);
+}
+
+static GtkPrintSettings *
+ev_print_operation_print_get_print_settings (EvPrintOperation *op)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ return gtk_print_operation_get_print_settings (print->op);
+}
+
+static void
+ev_print_operation_print_set_default_page_setup (EvPrintOperation *op,
+ GtkPageSetup *page_setup)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ gtk_print_operation_set_default_page_setup (print->op, page_setup);
+}
+
+static GtkPageSetup *
+ev_print_operation_print_get_default_page_setup (EvPrintOperation *op)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ return gtk_print_operation_get_default_page_setup (print->op);
+}
+
+static void
+ev_print_operation_print_set_job_name (EvPrintOperation *op,
+ const gchar *job_name)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ g_free (print->job_name);
+ print->job_name = g_strdup (job_name);
+
+ gtk_print_operation_set_job_name (print->op, print->job_name);
+}
+
+static const gchar *
+ev_print_operation_print_get_job_name (EvPrintOperation *op)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ if (!print->job_name) {
+ gchar *name;
+
+ g_object_get (print->op, "job_name", &name, NULL);
+ print->job_name = name;
+ }
+
+ return print->job_name;
+}
+
+static void
+ev_print_operation_print_run (EvPrintOperation *op,
+ GtkWindow *parent)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ gtk_print_operation_run (print->op,
+ GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ parent, NULL);
+}
+
+static void
+ev_print_operation_print_cancel (EvPrintOperation *op)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ gtk_print_operation_cancel (print->op);
+}
+
+static void
+ev_print_operation_print_get_error (EvPrintOperation *op,
+ GError **error)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
+
+ gtk_print_operation_get_error (print->op, error);
+}
+
+static void
+ev_print_operation_print_begin_print (EvPrintOperationPrint *print,
+ GtkPrintContext *context)
+{
+ EvPrintOperation *op = EV_PRINT_OPERATION (print);
+ gint n_pages;
+
+ n_pages = ev_page_cache_get_n_pages (ev_page_cache_get (op->document));
+ gtk_print_operation_set_n_pages (print->op, n_pages);
+ ev_print_operation_update_status (op, -1, n_pages, 0);
+
+ g_signal_emit (op, signals[BEGIN_PRINT], 0);
+}
+
+static void
+ev_print_operation_print_done (EvPrintOperationPrint *print,
+ GtkPrintOperationResult result)
+{
+ EvPrintOperation *op = EV_PRINT_OPERATION (print);
+
+ ev_print_operation_update_status (op, 0, print->n_pages_to_print, 1.0);
+
+ g_signal_emit (op, signals[DONE], 0, result);
+}
+
+static void
+ev_print_operation_print_status_changed (EvPrintOperationPrint *print)
+{
+#ifdef HAVE_GTK_PRINT_OPERATION_GET_N_PAGES_TO_PRINT
+ GtkPrintStatus status;
+
+ status = gtk_print_operation_get_status (print->op);
+ if (status == GTK_PRINT_STATUS_GENERATING_DATA)
+ print->n_pages_to_print = gtk_print_operation_get_n_pages_to_print (print->op);
+#endif
+}
+
+static void
+print_job_finished (EvJobPrint *job,
+ EvPrintOperationPrint *print)
+{
+ EvPrintOperation *op = EV_PRINT_OPERATION (print);
+
+ gtk_print_operation_draw_page_finish (print->op);
+#ifdef HAVE_GTK_PRINT_OPERATION_GET_N_PAGES_TO_PRINT
+ print->total++;
+ ev_print_operation_update_status (op, print->total,
+ print->n_pages_to_print,
+ print->total / (gdouble)print->n_pages_to_print);
+#endif
+ ev_job_print_set_cairo (job, NULL);
+}
+
+static void
+print_job_cancelled (EvJobPrint *job,
+ EvPrintOperationPrint *print)
+{
+ gtk_print_operation_cancel (print->op);
+}
+
+static void
+ev_print_operation_print_draw_page (EvPrintOperationPrint *print,
+ GtkPrintContext *context,
+ gint page)
+{
+ EvPrintOperation *op = EV_PRINT_OPERATION (print);
+ cairo_t *cr;
+ gdouble cr_width, cr_height;
+ gint width, height;
+
+ gtk_print_operation_set_defer_drawing (print->op);
+
+ if (!print->job_print) {
+ print->job_print = ev_job_print_new (op->document);
+ g_signal_connect (G_OBJECT (print->job_print), "finished",
+ G_CALLBACK (print_job_finished),
+ (gpointer)print);
+ g_signal_connect (G_OBJECT (print->job_print), "cancelled",
+ G_CALLBACK (print_job_cancelled),
+ (gpointer)print);
+ }
+
+ ev_job_print_set_page (EV_JOB_PRINT (print->job_print), page);
+
+ cr = gtk_print_context_get_cairo_context (context);
+ cr_width = gtk_print_context_get_width (context);
+ cr_height = gtk_print_context_get_height (context);
+ ev_page_cache_get_size (ev_page_cache_get (op->document),
+ page, 0, 1.0,
+ &width, &height);
+ cairo_scale (cr, cr_width / (gdouble)width, cr_height / (gdouble)height);
+
+ ev_job_print_set_cairo (EV_JOB_PRINT (print->job_print), cr);
+ ev_job_scheduler_push_job (print->job_print, EV_JOB_PRIORITY_NONE);
+}
+
+static void
+ev_print_operation_print_finalize (GObject *object)
+{
+ EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (object);
+
+ if (print->op) {
+ g_object_unref (print->op);
+ print->op = NULL;
+ }
+
+ if (print->job_name) {
+ g_free (print->job_name);
+ print->job_name = NULL;
+ }
+
+ if (print->job_print) {
+ if (!ev_job_is_finished (print->job_print))
+ ev_job_cancel (print->job_print);
+ g_signal_handlers_disconnect_by_func (print->job_print,
+ print_job_finished,
+ print);
+ g_signal_handlers_disconnect_by_func (print->job_print,
+ print_job_cancelled,
+ print);
+ g_object_unref (print->job_print);
+ print->job_print = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_print_operation_print_parent_class)->finalize) (object);
+}
+
+static void
+ev_print_operation_print_init (EvPrintOperationPrint *print)
+{
+ print->op = gtk_print_operation_new ();
+ g_signal_connect_swapped (print->op, "begin_print",
+ G_CALLBACK (ev_print_operation_print_begin_print),
+ print);
+ g_signal_connect_swapped (print->op, "done",
+ G_CALLBACK (ev_print_operation_print_done),
+ print);
+ g_signal_connect_swapped (print->op, "draw_page",
+ G_CALLBACK (ev_print_operation_print_draw_page),
+ print);
+ g_signal_connect_swapped (print->op, "status_changed",
+ G_CALLBACK (ev_print_operation_print_status_changed),
+ print);
+ gtk_print_operation_set_allow_async (print->op, TRUE);
+}
+
+static void
+ev_print_operation_print_class_init (EvPrintOperationPrintClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+ EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
+
+ ev_print_op_class->set_current_page = ev_print_operation_print_set_current_page;
+ ev_print_op_class->set_print_settings = ev_print_operation_print_set_print_settings;
+ ev_print_op_class->get_print_settings = ev_print_operation_print_get_print_settings;
+ ev_print_op_class->set_default_page_setup = ev_print_operation_print_set_default_page_setup;
+ ev_print_op_class->get_default_page_setup = ev_print_operation_print_get_default_page_setup;
+ ev_print_op_class->set_job_name = ev_print_operation_print_set_job_name;
+ ev_print_op_class->get_job_name = ev_print_operation_print_get_job_name;
+ ev_print_op_class->run = ev_print_operation_print_run;
+ ev_print_op_class->cancel = ev_print_operation_print_cancel;
+ ev_print_op_class->get_error = ev_print_operation_print_get_error;
+
+ g_object_class->finalize = ev_print_operation_print_finalize;
+}
+#endif /* GTK_CHECK_VERSION (2, 17, 1) */
+
+gboolean ev_print_operation_exists_for_document (EvDocument *document)
+{
+#if GTKUNIXPRINT_ENABLED
+#if GTK_CHECK_VERSION (2, 17, 1)
+ return (EV_IS_FILE_EXPORTER(document) || EV_IS_DOCUMENT_PRINT(document));
+#else
+ return EV_IS_FILE_EXPORTER(document);
+#endif
+#else /* ! GTKUNIXPRINT_ENABLED */
+#if GTK_CHECK_VERSION (2, 17, 1)
+ return EV_IS_DOCUMENT_PRINT(document);
+#else
+ return FALSE;
+#endif
+#endif /* GTKUNIXPRINT_ENABLED */
+}
+