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, see <http://www.gnu.org/licenses/>.
22 #include <sys/types.h>
32 #include <glib/gi18n-lib.h>
35 #include "gtkprinter-private.h"
37 #include "gtkprintbackendlpr.h"
39 typedef struct _GtkPrintBackendLprClass GtkPrintBackendLprClass;
41 #define GTK_PRINT_BACKEND_LPR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_LPR, GtkPrintBackendLprClass))
42 #define GTK_IS_PRINT_BACKEND_LPR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_LPR))
43 #define GTK_PRINT_BACKEND_LPR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_LPR, GtkPrintBackendLprClass))
45 #define _LPR_MAX_CHUNK_SIZE 8192
47 static GType print_backend_lpr_type = 0;
49 struct _GtkPrintBackendLprClass
51 GtkPrintBackendClass parent_class;
54 struct _GtkPrintBackendLpr
56 GtkPrintBackend parent_instance;
59 static GObjectClass *backend_parent_class;
61 static void gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class);
62 static void gtk_print_backend_lpr_init (GtkPrintBackendLpr *impl);
63 static void lpr_printer_get_settings_from_options (GtkPrinter *printer,
64 GtkPrinterOptionSet *options,
65 GtkPrintSettings *settings);
66 static GtkPrinterOptionSet *lpr_printer_get_options (GtkPrinter *printer,
67 GtkPrintSettings *settings,
68 GtkPageSetup *page_setup,
69 GtkPrintCapabilities capabilities);
70 static void lpr_printer_prepare_for_print (GtkPrinter *printer,
71 GtkPrintJob *print_job,
72 GtkPrintSettings *settings,
73 GtkPageSetup *page_setup);
74 static cairo_surface_t * lpr_printer_create_cairo_surface (GtkPrinter *printer,
75 GtkPrintSettings *settings,
78 GIOChannel *cache_io);
79 static void gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
82 GtkPrintJobCompleteFunc callback,
84 GDestroyNotify dnotify);
87 gtk_print_backend_lpr_register_type (GTypeModule *module)
89 const GTypeInfo print_backend_lpr_info =
91 sizeof (GtkPrintBackendLprClass),
93 NULL, /* base_finalize */
94 (GClassInitFunc) gtk_print_backend_lpr_class_init,
95 NULL, /* class_finalize */
96 NULL, /* class_data */
97 sizeof (GtkPrintBackendLpr),
99 (GInstanceInitFunc) gtk_print_backend_lpr_init,
102 print_backend_lpr_type = g_type_module_register_type (module,
103 GTK_TYPE_PRINT_BACKEND,
104 "GtkPrintBackendLpr",
105 &print_backend_lpr_info, 0);
109 pb_module_init (GTypeModule *module)
111 gtk_print_backend_lpr_register_type (module);
115 pb_module_exit (void)
120 G_MODULE_EXPORT GtkPrintBackend *
121 pb_module_create (void)
123 return gtk_print_backend_lpr_new ();
130 gtk_print_backend_lpr_get_type (void)
132 return print_backend_lpr_type;
136 * gtk_print_backend_lpr_new:
138 * Creates a new #GtkPrintBackendLpr object. #GtkPrintBackendLpr
139 * implements the #GtkPrintBackend interface with direct access to
140 * the filesystem using Unix/Linux API calls
142 * Return value: the new #GtkPrintBackendLpr object
145 gtk_print_backend_lpr_new (void)
147 return g_object_new (GTK_TYPE_PRINT_BACKEND_LPR, NULL);
151 gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class)
153 GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
155 backend_parent_class = g_type_class_peek_parent (class);
157 backend_class->print_stream = gtk_print_backend_lpr_print_stream;
158 backend_class->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
159 backend_class->printer_get_options = lpr_printer_get_options;
160 backend_class->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
161 backend_class->printer_prepare_for_print = lpr_printer_prepare_for_print;
164 static cairo_status_t
165 _cairo_write (void *closure,
166 const unsigned char *data,
169 GIOChannel *io = (GIOChannel *)closure;
176 g_print ("LPR Backend: Writting %i byte chunk to temp file\n", length));
180 g_io_channel_write_chars (io, (const gchar*)data, length, &written, &error);
185 g_print ("LPR Backend: Error writting to temp file, %s\n", error->message));
187 g_error_free (error);
188 return CAIRO_STATUS_WRITE_ERROR;
192 g_print ("LPR Backend: Wrote %" G_GSIZE_FORMAT " bytes to temp file\n", written));
198 return CAIRO_STATUS_SUCCESS;
201 static cairo_surface_t *
202 lpr_printer_create_cairo_surface (GtkPrinter *printer,
203 GtkPrintSettings *settings,
206 GIOChannel *cache_io)
208 cairo_surface_t *surface;
210 surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height);
212 cairo_surface_set_fallback_resolution (surface,
213 2.0 * gtk_print_settings_get_printer_lpi (settings),
214 2.0 * gtk_print_settings_get_printer_lpi (settings));
220 GtkPrintBackend *backend;
221 GtkPrintJobCompleteFunc callback;
224 GDestroyNotify dnotify;
230 lpr_print_cb (GtkPrintBackendLpr *print_backend,
234 _PrintStreamData *ps = (_PrintStreamData *) user_data;
237 g_io_channel_unref (ps->in);
240 ps->callback (ps->job, ps->user_data, error);
243 ps->dnotify (ps->user_data);
245 gtk_print_job_set_status (ps->job,
246 error ? GTK_PRINT_STATUS_FINISHED_ABORTED
247 : GTK_PRINT_STATUS_FINISHED);
250 g_object_unref (ps->job);
256 lpr_write (GIOChannel *source,
260 gchar buf[_LPR_MAX_CHUNK_SIZE];
264 _PrintStreamData *ps = (_PrintStreamData *) user_data;
269 g_io_channel_read_chars (source,
275 if (status != G_IO_STATUS_ERROR)
279 g_io_channel_write_chars (ps->in,
286 if (error != NULL || status == G_IO_STATUS_EOF)
288 lpr_print_cb (GTK_PRINT_BACKEND_LPR (ps->backend),
295 g_print ("LPR Backend: %s\n", error->message));
297 g_error_free (error);
304 g_print ("LPR Backend: Writting %" G_GSIZE_FORMAT " byte chunk to lpr pipe\n", bytes_read));
310 #define LPR_COMMAND "lpr"
313 gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
316 GtkPrintJobCompleteFunc callback,
318 GDestroyNotify dnotify)
320 GError *print_error = NULL;
321 _PrintStreamData *ps;
322 GtkPrintSettings *settings;
326 const char *cmd_line;
328 settings = gtk_print_job_get_settings (job);
330 cmd_line = gtk_print_settings_get (settings, "lpr-commandline");
331 if (cmd_line == NULL)
332 cmd_line = LPR_COMMAND;
334 ps = g_new0 (_PrintStreamData, 1);
335 ps->callback = callback;
336 ps->user_data = user_data;
337 ps->dnotify = dnotify;
338 ps->job = g_object_ref (job);
341 /* spawn lpr with pipes and pipe ps file to lpr */
342 if (!g_shell_parse_argv (cmd_line, &argc, &argv, &print_error))
345 if (!g_spawn_async_with_pipes (NULL,
358 ps->in = g_io_channel_unix_new (in_fd);
360 g_io_channel_set_encoding (ps->in, NULL, &print_error);
361 if (print_error != NULL)
364 g_io_channel_unref (ps->in);
369 g_io_channel_set_close_on_unref (ps->in, TRUE);
371 g_io_add_watch (data_io,
372 G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
380 if (print_error != NULL)
382 lpr_print_cb (GTK_PRINT_BACKEND_LPR (print_backend),
384 g_error_free (print_error);
389 gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend)
393 printer = gtk_printer_new (_("Print to LPR"),
394 GTK_PRINT_BACKEND (backend),
396 gtk_printer_set_has_details (printer, TRUE);
397 gtk_printer_set_icon_name (printer, "printer");
398 gtk_printer_set_is_active (printer, TRUE);
399 gtk_printer_set_is_default (printer, TRUE);
401 gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
402 g_object_unref (printer);
403 gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (backend));
406 static GtkPrinterOptionSet *
407 lpr_printer_get_options (GtkPrinter *printer,
408 GtkPrintSettings *settings,
409 GtkPageSetup *page_setup,
410 GtkPrintCapabilities capabilities)
412 GtkPrinterOptionSet *set;
413 GtkPrinterOption *option;
415 char *n_up[] = {"1", "2", "4", "6", "9", "16" };
417 set = gtk_printer_option_set_new ();
419 option = gtk_printer_option_new ("gtk-n-up", _("Pages Per Sheet"), GTK_PRINTER_OPTION_TYPE_PICKONE);
420 gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
422 gtk_printer_option_set (option, "1");
423 gtk_printer_option_set_add (set, option);
424 g_object_unref (option);
426 option = gtk_printer_option_new ("gtk-main-page-custom-input", _("Command Line"), GTK_PRINTER_OPTION_TYPE_STRING);
427 gtk_printer_option_set_activates_default (option, TRUE);
428 option->group = g_strdup ("GtkPrintDialogExtension");
429 if (settings != NULL &&
430 (command = gtk_print_settings_get (settings, "lpr-commandline"))!= NULL)
431 gtk_printer_option_set (option, command);
433 gtk_printer_option_set (option, LPR_COMMAND);
434 gtk_printer_option_set_add (set, option);
440 lpr_printer_get_settings_from_options (GtkPrinter *printer,
441 GtkPrinterOptionSet *options,
442 GtkPrintSettings *settings)
444 GtkPrinterOption *option;
446 option = gtk_printer_option_set_lookup (options, "gtk-main-page-custom-input");
448 gtk_print_settings_set (settings, "lpr-commandline", option->value);
450 option = gtk_printer_option_set_lookup (options, "gtk-n-up");
452 gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP, option->value);
454 option = gtk_printer_option_set_lookup (options, "gtk-n-up-layout");
456 gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, option->value);
460 lpr_printer_prepare_for_print (GtkPrinter *printer,
461 GtkPrintJob *print_job,
462 GtkPrintSettings *settings,
463 GtkPageSetup *page_setup)
467 GtkPageRange *ranges;
470 pages = gtk_print_settings_get_print_pages (settings);
471 gtk_print_job_set_pages (print_job, pages);
473 if (pages == GTK_PRINT_PAGES_RANGES)
474 ranges = gtk_print_settings_get_page_ranges (settings, &n_ranges);
481 gtk_print_job_set_page_ranges (print_job, ranges, n_ranges);
482 gtk_print_job_set_collate (print_job, gtk_print_settings_get_collate (settings));
483 gtk_print_job_set_reverse (print_job, gtk_print_settings_get_reverse (settings));
484 gtk_print_job_set_num_copies (print_job, gtk_print_settings_get_n_copies (settings));
485 gtk_print_job_set_n_up (print_job, gtk_print_settings_get_number_up (settings));
486 gtk_print_job_set_n_up_layout (print_job, gtk_print_settings_get_number_up_layout (settings));
488 scale = gtk_print_settings_get_scale (settings);
490 gtk_print_job_set_scale (print_job, scale / 100.0);
492 gtk_print_job_set_page_set (print_job, gtk_print_settings_get_page_set (settings));
493 gtk_print_job_set_rotate (print_job, TRUE);