1 /* GTK - The GIMP Toolkit
2 * gtkprintbackendlpr.c: Default implementation of GtkPrintBackend
4 * Copyright (C) 2003, 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.
23 #include <sys/types.h>
34 #include <glib/gi18n-lib.h>
36 #include "gtkprintoperation.h"
38 #include "gtkprintbackendlpr.h"
40 #include "gtkprinter.h"
42 typedef struct _GtkPrintBackendLprClass GtkPrintBackendLprClass;
44 #define GTK_PRINT_BACKEND_LPR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_LPR, GtkPrintBackendLprClass))
45 #define GTK_IS_PRINT_BACKEND_LPR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_LPR))
46 #define GTK_PRINT_BACKEND_LPR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_LPR, GtkPrintBackendLprClass))
48 #define _LPR_MAX_CHUNK_SIZE 8192
50 static GType print_backend_lpr_type = 0;
52 struct _GtkPrintBackendLprClass
54 GObjectClass parent_class;
57 struct _GtkPrintBackendLpr
59 GObject parent_instance;
66 static GObjectClass *backend_parent_class;
68 static void gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class);
69 static void gtk_print_backend_lpr_iface_init (GtkPrintBackendIface *iface);
70 static void gtk_print_backend_lpr_init (GtkPrintBackendLpr *impl);
71 static void gtk_print_backend_lpr_finalize (GObject *object);
72 static GList * lpr_request_printer_list (GtkPrintBackend *print_backend);
73 static void lpr_printer_get_settings_from_options (GtkPrinter *printer,
74 GtkPrinterOptionSet *options,
75 GtkPrintSettings *settings);
76 static gboolean lpr_printer_mark_conflicts (GtkPrinter *printer,
77 GtkPrinterOptionSet *options);
78 static GtkPrinterOptionSet *lpr_printer_get_options (GtkPrinter *printer,
79 GtkPrintSettings *settings,
80 GtkPageSetup *page_setup);
81 static void lpr_printer_prepare_for_print (GtkPrinter *printer,
82 GtkPrintJob *print_job,
83 GtkPrintSettings *settings,
84 GtkPageSetup *page_setup);
85 static void lpr_printer_get_hard_margins (GtkPrinter *printer,
90 static void lpr_printer_request_details (GtkPrinter *printer);
91 static GList * lpr_printer_list_papers (GtkPrinter *printer);
94 gtk_print_backend_lpr_register_type (GTypeModule *module)
96 if (!print_backend_lpr_type)
98 static const GTypeInfo print_backend_lpr_info =
100 sizeof (GtkPrintBackendLprClass),
101 NULL, /* base_init */
102 NULL, /* base_finalize */
103 (GClassInitFunc) gtk_print_backend_lpr_class_init,
104 NULL, /* class_finalize */
105 NULL, /* class_data */
106 sizeof (GtkPrintBackendLpr),
108 (GInstanceInitFunc) gtk_print_backend_lpr_init,
111 static const GInterfaceInfo print_backend_info =
113 (GInterfaceInitFunc) gtk_print_backend_lpr_iface_init, /* interface_init */
114 NULL, /* interface_finalize */
115 NULL /* interface_data */
118 print_backend_lpr_type = g_type_module_register_type (module,
120 "GtkPrintBackendLpr",
121 &print_backend_lpr_info, 0);
122 g_type_module_add_interface (module,
123 print_backend_lpr_type,
124 GTK_TYPE_PRINT_BACKEND,
125 &print_backend_info);
132 pb_module_init (GTypeModule *module)
134 gtk_print_backend_lpr_register_type (module);
138 pb_module_exit (void)
143 G_MODULE_EXPORT GtkPrintBackend *
144 pb_module_create (void)
146 return gtk_print_backend_lpr_new ();
153 gtk_print_backend_lpr_get_type (void)
155 return print_backend_lpr_type;
159 * gtk_print_backend_lpr_new:
161 * Creates a new #GtkPrintBackendLpr object. #GtkPrintBackendLpr
162 * implements the #GtkPrintBackend interface with direct access to
163 * the filesystem using Unix/Linux API calls
165 * Return value: the new #GtkPrintBackendLpr object
168 gtk_print_backend_lpr_new (void)
170 return g_object_new (GTK_TYPE_PRINT_BACKEND_LPR, NULL);
174 gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class)
176 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
178 backend_parent_class = g_type_class_peek_parent (class);
180 gobject_class->finalize = gtk_print_backend_lpr_finalize;
183 static cairo_status_t
184 _cairo_write (void *cache_fd_as_pointer,
185 const unsigned char *data,
188 cairo_status_t result;
190 cache_fd = GPOINTER_TO_INT (cache_fd_as_pointer);
192 result = CAIRO_STATUS_WRITE_ERROR;
194 /* write out the buffer */
195 if (write (cache_fd, data, length) != -1)
196 result = CAIRO_STATUS_SUCCESS;
202 static cairo_surface_t *
203 lpr_printer_create_cairo_surface (GtkPrinter *printer,
208 cairo_surface_t *surface;
210 surface = cairo_ps_surface_create_for_stream (_cairo_write, GINT_TO_POINTER (cache_fd), width, height);
212 /* TODO: DPI from settings object? */
213 cairo_ps_surface_set_dpi (surface, 300, 300);
219 gtk_print_backend_lpr_find_printer (GtkPrintBackend *print_backend,
220 const gchar *printer_name)
222 GtkPrintBackendLpr *lpr_print_backend;
225 lpr_print_backend = GTK_PRINT_BACKEND_LPR (print_backend);
228 if (strcmp (gtk_printer_get_name (lpr_print_backend->printer), printer_name) == 0)
229 printer = lpr_print_backend->printer;
235 GtkPrintBackend *backend;
236 GtkPrintJobCompleteFunc callback;
239 GDestroyNotify dnotify;
248 lpr_print_cb (GtkPrintBackendLpr *print_backend,
252 _PrintStreamData *ps = (_PrintStreamData *) user_data;
264 ps->callback (ps->job, ps->user_data, error);
267 ps->dnotify (ps->user_data);
269 gtk_print_job_set_status (ps->job,
270 (error != NULL)?GTK_PRINT_STATUS_FINISHED_ABORTED:GTK_PRINT_STATUS_FINISHED);
273 g_object_unref (ps->job);
279 lpr_write (GIOChannel *source,
283 gchar buf[_LPR_MAX_CHUNK_SIZE];
286 _PrintStreamData *ps = (_PrintStreamData *) user_data;
291 source_fd = g_io_channel_unix_get_fd (source);
293 bytes_read = read (source_fd,
295 _LPR_MAX_CHUNK_SIZE);
299 if (write (ps->in, buf, bytes_read) == -1)
301 error = g_error_new (GTK_PRINT_ERROR,
302 GTK_PRINT_ERROR_INTERNAL_ERROR,
306 else if (bytes_read == -1)
308 error = g_error_new (GTK_PRINT_ERROR,
309 GTK_PRINT_ERROR_INTERNAL_ERROR,
313 if (bytes_read == 0 || error != NULL)
315 lpr_print_cb (GTK_PRINT_BACKEND_LPR (ps->backend), error, user_data);
323 #define LPR_COMMAND "lpr"
326 gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
329 GtkPrintJobCompleteFunc callback,
331 GDestroyNotify dnotify)
335 _PrintStreamData *ps;
336 GtkPrintSettings *settings;
337 GIOChannel *send_channel;
340 const char *cmd_line;
342 printer = gtk_print_job_get_printer (job);
343 settings = gtk_print_job_get_settings (job);
347 cmd_line = gtk_print_settings_get (settings, "lpr-commandline");
348 if (cmd_line == NULL)
349 cmd_line = LPR_COMMAND;
351 ps = g_new0 (_PrintStreamData, 1);
352 ps->callback = callback;
353 ps->user_data = user_data;
354 ps->dnotify = dnotify;
355 ps->job = g_object_ref (job);
360 /* spawn lpr with pipes and pipe ps file to lpr */
361 if (!g_shell_parse_argv (cmd_line,
366 lpr_print_cb (GTK_PRINT_BACKEND_LPR (print_backend),
371 if (!g_spawn_async_with_pipes (NULL,
383 lpr_print_cb (GTK_PRINT_BACKEND_LPR (print_backend),
390 send_channel = g_io_channel_unix_new (data_fd);
392 g_io_add_watch (send_channel,
393 G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
403 gtk_print_backend_lpr_iface_init (GtkPrintBackendIface *iface)
405 iface->get_printer_list = lpr_request_printer_list;
406 iface->find_printer = gtk_print_backend_lpr_find_printer;
407 iface->print_stream = gtk_print_backend_lpr_print_stream;
408 iface->printer_request_details = lpr_printer_request_details;
409 iface->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
410 iface->printer_get_options = lpr_printer_get_options;
411 iface->printer_mark_conflicts = lpr_printer_mark_conflicts;
412 iface->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
413 iface->printer_prepare_for_print = lpr_printer_prepare_for_print;
414 iface->printer_list_papers = lpr_printer_list_papers;
415 iface->printer_get_hard_margins = lpr_printer_get_hard_margins;
419 lpr_request_printer_list (GtkPrintBackend *backend)
422 GtkPrintBackendLpr *lpr_backend;
426 lpr_backend = GTK_PRINT_BACKEND_LPR (backend);
428 if (lpr_backend->printer)
429 l = g_list_append (l, lpr_backend->printer);
435 gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend_lpr)
439 printer = gtk_printer_new (_("Print to LPR"),
440 GTK_PRINT_BACKEND (backend_lpr),
442 gtk_printer_set_has_details (printer, TRUE);
443 gtk_printer_set_icon_name (printer, "printer");
444 gtk_printer_set_is_active (printer, TRUE);
446 backend_lpr->printer = printer;
450 gtk_print_backend_lpr_finalize (GObject *object)
452 GtkPrintBackendLpr *backend_lpr;
454 backend_lpr = GTK_PRINT_BACKEND_LPR (object);
456 g_object_unref (backend_lpr->printer);
458 backend_parent_class->finalize (object);
462 lpr_printer_request_details (GtkPrinter *printer)
466 static GtkPrinterOptionSet *
467 lpr_printer_get_options (GtkPrinter *printer,
468 GtkPrintSettings *settings,
469 GtkPageSetup *page_setup)
471 GtkPrinterOptionSet *set;
472 GtkPrinterOption *option;
474 char *n_up[] = {"1", "2", "4", "6", "9", "16" };
476 set = gtk_printer_option_set_new ();
478 option = gtk_printer_option_new ("gtk-n-up", _("Pages Per Sheet"), GTK_PRINTER_OPTION_TYPE_PICKONE);
479 gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
481 gtk_printer_option_set (option, "1");
482 gtk_printer_option_set_add (set, option);
483 g_object_unref (option);
485 option = gtk_printer_option_new ("gtk-main-page-custom-input", _("Command Line"), GTK_PRINTER_OPTION_TYPE_STRING);
486 option->group = g_strdup ("GtkPrintDialogExtention");
487 if (settings != NULL &&
488 (command = gtk_print_settings_get (settings, "lpr-commandline"))!= NULL)
489 gtk_printer_option_set (option, command);
491 gtk_printer_option_set (option, LPR_COMMAND);
492 gtk_printer_option_set_add (set, option);
499 lpr_printer_mark_conflicts (GtkPrinter *printer,
500 GtkPrinterOptionSet *options)
506 lpr_printer_get_settings_from_options (GtkPrinter *printer,
507 GtkPrinterOptionSet *options,
508 GtkPrintSettings *settings)
510 GtkPrinterOption *option;
512 option = gtk_printer_option_set_lookup (options, "gtk-main-page-custom-input");
513 gtk_print_settings_set (settings, "lpr-commandline", option->value);
517 lpr_printer_prepare_for_print (GtkPrinter *printer,
518 GtkPrintJob *print_job,
519 GtkPrintSettings *settings,
520 GtkPageSetup *page_setup)
524 print_job->print_pages = gtk_print_settings_get_print_pages (settings);
525 print_job->page_ranges = NULL;
526 print_job->num_page_ranges = 0;
528 if (print_job->print_pages == GTK_PRINT_PAGES_RANGES)
529 print_job->page_ranges =
530 gtk_print_settings_get_page_ranges (settings,
531 &print_job->num_page_ranges);
533 print_job->collate = gtk_print_settings_get_collate (settings);
534 print_job->reverse = gtk_print_settings_get_reverse (settings);
535 print_job->num_copies = gtk_print_settings_get_num_copies (settings);
537 scale = gtk_print_settings_get_scale (settings);
539 print_job->scale = scale/100.0;
541 print_job->page_set = gtk_print_settings_get_page_set (settings);
542 print_job->rotate_to_orientation = TRUE;
546 lpr_printer_get_hard_margins (GtkPrinter *printer,
559 lpr_printer_list_papers (GtkPrinter *printer)