1 /* GTK - The GIMP Toolkit
2 * gtkprintbackendlpr.c: LPR implementation of GtkPrintBackend
4 * Copyright (C) 2006, 2007 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.
24 #include <sys/types.h>
34 #include <glib/gi18n-lib.h>
37 #include "gtkprinter-private.h"
39 #include "gtkprintbackendlpr.h"
41 typedef struct _GtkPrintBackendLprClass GtkPrintBackendLprClass;
43 #define GTK_PRINT_BACKEND_LPR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_LPR, GtkPrintBackendLprClass))
44 #define GTK_IS_PRINT_BACKEND_LPR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_LPR))
45 #define GTK_PRINT_BACKEND_LPR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_LPR, GtkPrintBackendLprClass))
47 #define _LPR_MAX_CHUNK_SIZE 8192
49 static GType print_backend_lpr_type = 0;
51 struct _GtkPrintBackendLprClass
53 GtkPrintBackendClass parent_class;
56 struct _GtkPrintBackendLpr
58 GtkPrintBackend parent_instance;
61 static GObjectClass *backend_parent_class;
63 static void gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class);
64 static void gtk_print_backend_lpr_init (GtkPrintBackendLpr *impl);
65 static void lpr_printer_get_settings_from_options (GtkPrinter *printer,
66 GtkPrinterOptionSet *options,
67 GtkPrintSettings *settings);
68 static GtkPrinterOptionSet *lpr_printer_get_options (GtkPrinter *printer,
69 GtkPrintSettings *settings,
70 GtkPageSetup *page_setup,
71 GtkPrintCapabilities capabilities);
72 static void lpr_printer_prepare_for_print (GtkPrinter *printer,
73 GtkPrintJob *print_job,
74 GtkPrintSettings *settings,
75 GtkPageSetup *page_setup);
76 static cairo_surface_t * lpr_printer_create_cairo_surface (GtkPrinter *printer,
77 GtkPrintSettings *settings,
80 GIOChannel *cache_io);
81 static void gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
84 GtkPrintJobCompleteFunc callback,
86 GDestroyNotify dnotify);
89 gtk_print_backend_lpr_register_type (GTypeModule *module)
91 static const GTypeInfo print_backend_lpr_info =
93 sizeof (GtkPrintBackendLprClass),
95 NULL, /* base_finalize */
96 (GClassInitFunc) gtk_print_backend_lpr_class_init,
97 NULL, /* class_finalize */
98 NULL, /* class_data */
99 sizeof (GtkPrintBackendLpr),
101 (GInstanceInitFunc) gtk_print_backend_lpr_init,
104 print_backend_lpr_type = g_type_module_register_type (module,
105 GTK_TYPE_PRINT_BACKEND,
106 "GtkPrintBackendLpr",
107 &print_backend_lpr_info, 0);
111 pb_module_init (GTypeModule *module)
113 gtk_print_backend_lpr_register_type (module);
117 pb_module_exit (void)
122 G_MODULE_EXPORT GtkPrintBackend *
123 pb_module_create (void)
125 return gtk_print_backend_lpr_new ();
132 gtk_print_backend_lpr_get_type (void)
134 return print_backend_lpr_type;
138 * gtk_print_backend_lpr_new:
140 * Creates a new #GtkPrintBackendLpr object. #GtkPrintBackendLpr
141 * implements the #GtkPrintBackend interface with direct access to
142 * the filesystem using Unix/Linux API calls
144 * Return value: the new #GtkPrintBackendLpr object
147 gtk_print_backend_lpr_new (void)
149 return g_object_new (GTK_TYPE_PRINT_BACKEND_LPR, NULL);
153 gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class)
155 GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
157 backend_parent_class = g_type_class_peek_parent (class);
159 backend_class->print_stream = gtk_print_backend_lpr_print_stream;
160 backend_class->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
161 backend_class->printer_get_options = lpr_printer_get_options;
162 backend_class->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
163 backend_class->printer_prepare_for_print = lpr_printer_prepare_for_print;
166 static cairo_status_t
167 _cairo_write (void *closure,
168 const unsigned char *data,
171 GIOChannel *io = (GIOChannel *)closure;
178 g_print ("LPR Backend: Writting %i byte chunk to temp file\n", length));
182 g_io_channel_write_chars (io, data, length, &written, &error);
187 g_print ("LPR Backend: Error writting to temp file, %s\n", error->message));
189 g_error_free (error);
190 return CAIRO_STATUS_WRITE_ERROR;
194 g_print ("LPR Backend: Wrote %i bytes to temp file\n", written));
200 return CAIRO_STATUS_SUCCESS;
203 static cairo_surface_t *
204 lpr_printer_create_cairo_surface (GtkPrinter *printer,
205 GtkPrintSettings *settings,
208 GIOChannel *cache_io)
210 cairo_surface_t *surface;
212 surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height);
214 /* TODO: DPI from settings object? */
215 cairo_surface_set_fallback_resolution (surface, 300, 300);
221 GtkPrintBackend *backend;
222 GtkPrintJobCompleteFunc callback;
225 GDestroyNotify dnotify;
231 lpr_print_cb (GtkPrintBackendLpr *print_backend,
235 _PrintStreamData *ps = (_PrintStreamData *) user_data;
238 g_io_channel_unref (ps->in);
241 ps->callback (ps->job, ps->user_data, error);
244 ps->dnotify (ps->user_data);
246 gtk_print_job_set_status (ps->job,
247 error ? GTK_PRINT_STATUS_FINISHED_ABORTED
248 : GTK_PRINT_STATUS_FINISHED);
251 g_object_unref (ps->job);
257 lpr_write (GIOChannel *source,
261 gchar buf[_LPR_MAX_CHUNK_SIZE];
265 _PrintStreamData *ps = (_PrintStreamData *) user_data;
270 g_io_channel_read_chars (source,
276 if (status != G_IO_STATUS_ERROR)
280 g_io_channel_write_chars (ps->in,
287 if (error != NULL || status == G_IO_STATUS_EOF)
289 lpr_print_cb (GTK_PRINT_BACKEND_LPR (ps->backend),
293 g_error_free (error);
298 g_print ("LPR Backend: %s\n", error->message));
300 g_error_free (error);
307 g_print ("LPR Backend: Writting %i byte chunk to lpr pipe\n", bytes_read));
313 #define LPR_COMMAND "lpr"
316 gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
319 GtkPrintJobCompleteFunc callback,
321 GDestroyNotify dnotify)
323 GError *print_error = NULL;
325 _PrintStreamData *ps;
326 GtkPrintSettings *settings;
330 const char *cmd_line;
332 printer = gtk_print_job_get_printer (job);
333 settings = gtk_print_job_get_settings (job);
335 cmd_line = gtk_print_settings_get (settings, "lpr-commandline");
336 if (cmd_line == NULL)
337 cmd_line = LPR_COMMAND;
339 ps = g_new0 (_PrintStreamData, 1);
340 ps->callback = callback;
341 ps->user_data = user_data;
342 ps->dnotify = dnotify;
343 ps->job = g_object_ref (job);
346 /* spawn lpr with pipes and pipe ps file to lpr */
347 if (!g_shell_parse_argv (cmd_line, &argc, &argv, &print_error))
350 if (!g_spawn_async_with_pipes (NULL,
363 ps->in = g_io_channel_unix_new (in_fd);
365 g_io_channel_set_encoding (ps->in, NULL, &print_error);
366 if (print_error != NULL)
369 g_io_channel_unref (ps->in);
374 g_io_channel_set_close_on_unref (ps->in, TRUE);
376 g_io_add_watch (data_io,
377 G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
385 if (print_error != NULL)
387 lpr_print_cb (GTK_PRINT_BACKEND_LPR (print_backend),
389 g_error_free (print_error);
394 gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend)
398 printer = gtk_printer_new (_("Print to LPR"),
399 GTK_PRINT_BACKEND (backend),
401 gtk_printer_set_has_details (printer, TRUE);
402 gtk_printer_set_icon_name (printer, "gtk-print");
403 gtk_printer_set_is_active (printer, TRUE);
404 gtk_printer_set_is_default (printer, TRUE);
406 gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
407 g_object_unref (printer);
408 gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (backend));
411 static GtkPrinterOptionSet *
412 lpr_printer_get_options (GtkPrinter *printer,
413 GtkPrintSettings *settings,
414 GtkPageSetup *page_setup,
415 GtkPrintCapabilities capabilities)
417 GtkPrinterOptionSet *set;
418 GtkPrinterOption *option;
420 char *n_up[] = {"1", "2", "4", "6", "9", "16" };
422 set = gtk_printer_option_set_new ();
424 option = gtk_printer_option_new ("gtk-n-up", _("Pages Per Sheet"), GTK_PRINTER_OPTION_TYPE_PICKONE);
425 gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
427 gtk_printer_option_set (option, "1");
428 gtk_printer_option_set_add (set, option);
429 g_object_unref (option);
431 option = gtk_printer_option_new ("gtk-main-page-custom-input", _("Command Line"), GTK_PRINTER_OPTION_TYPE_STRING);
432 option->group = g_strdup ("GtkPrintDialogExtension");
433 if (settings != NULL &&
434 (command = gtk_print_settings_get (settings, "lpr-commandline"))!= NULL)
435 gtk_printer_option_set (option, command);
437 gtk_printer_option_set (option, LPR_COMMAND);
438 gtk_printer_option_set_add (set, option);
444 lpr_printer_get_settings_from_options (GtkPrinter *printer,
445 GtkPrinterOptionSet *options,
446 GtkPrintSettings *settings)
448 GtkPrinterOption *option;
450 option = gtk_printer_option_set_lookup (options, "gtk-main-page-custom-input");
451 gtk_print_settings_set (settings, "lpr-commandline", option->value);
455 lpr_printer_prepare_for_print (GtkPrinter *printer,
456 GtkPrintJob *print_job,
457 GtkPrintSettings *settings,
458 GtkPageSetup *page_setup)
462 print_job->print_pages = gtk_print_settings_get_print_pages (settings);
463 print_job->page_ranges = NULL;
464 print_job->num_page_ranges = 0;
466 if (print_job->print_pages == GTK_PRINT_PAGES_RANGES)
467 print_job->page_ranges =
468 gtk_print_settings_get_page_ranges (settings,
469 &print_job->num_page_ranges);
471 print_job->collate = gtk_print_settings_get_collate (settings);
472 print_job->reverse = gtk_print_settings_get_reverse (settings);
473 print_job->num_copies = gtk_print_settings_get_n_copies (settings);
475 scale = gtk_print_settings_get_scale (settings);
477 print_job->scale = scale/100.0;
479 print_job->page_set = gtk_print_settings_get_page_set (settings);
480 print_job->rotate_to_orientation = TRUE;