2 * Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
3 * Copyright (C) 2011 Richard Hughes <rhughes@redhat.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 #include <glib/gi18n-lib.h>
28 #include "gtkprintercups.h"
35 static void gtk_printer_cups_init (GtkPrinterCups *printer);
36 static void gtk_printer_cups_class_init (GtkPrinterCupsClass *class);
37 static void gtk_printer_cups_finalize (GObject *object);
39 static GtkPrinterClass *gtk_printer_cups_parent_class;
40 static GType gtk_printer_cups_type = 0;
42 static void gtk_printer_cups_set_property (GObject *object,
46 static void gtk_printer_cups_get_property (GObject *object,
52 gtk_printer_cups_register_type (GTypeModule *module)
54 const GTypeInfo object_info =
56 sizeof (GtkPrinterCupsClass),
58 (GBaseFinalizeFunc) NULL,
59 (GClassInitFunc) gtk_printer_cups_class_init,
60 NULL, /* class_finalize */
61 NULL, /* class_data */
62 sizeof (GtkPrinterCups),
64 (GInstanceInitFunc) gtk_printer_cups_init,
67 gtk_printer_cups_type = g_type_module_register_type (module,
74 gtk_printer_cups_get_type (void)
76 return gtk_printer_cups_type;
80 gtk_printer_cups_class_init (GtkPrinterCupsClass *class)
82 GObjectClass *object_class = (GObjectClass *) class;
84 object_class->finalize = gtk_printer_cups_finalize;
85 object_class->set_property = gtk_printer_cups_set_property;
86 object_class->get_property = gtk_printer_cups_get_property;
88 gtk_printer_cups_parent_class = g_type_class_peek_parent (class);
90 g_object_class_install_property (G_OBJECT_CLASS (class),
92 g_param_spec_string ("profile-title",
93 P_("Color Profile Title"),
94 P_("The title of the color profile to use"),
100 gtk_printer_cups_init (GtkPrinterCups *printer)
102 printer->device_uri = NULL;
103 printer->printer_uri = NULL;
105 printer->hostname = NULL;
107 printer->ppd_name = NULL;
108 printer->ppd_file = NULL;
109 printer->default_cover_before = NULL;
110 printer->default_cover_after = NULL;
111 printer->remote = FALSE;
112 printer->get_remote_ppd_poll = 0;
113 printer->get_remote_ppd_attempts = 0;
114 printer->remote_cups_connection_test = NULL;
115 printer->auth_info_required = NULL;
116 printer->default_number_up = 1;
117 #ifdef HAVE_AVAHI_BROWSING
118 printer->avahi_browsed = FALSE;
119 printer->avahi_name = NULL;
120 printer->avahi_type = NULL;
121 printer->avahi_domain = NULL;
123 printer->ipp_version_major = 1;
124 printer->ipp_version_minor = 1;
125 printer->supports_copies = FALSE;
126 printer->supports_collate = FALSE;
127 printer->supports_number_up = FALSE;
131 gtk_printer_cups_finalize (GObject *object)
133 GtkPrinterCups *printer;
135 g_return_if_fail (object != NULL);
137 printer = GTK_PRINTER_CUPS (object);
139 g_free (printer->device_uri);
140 g_free (printer->printer_uri);
141 g_free (printer->hostname);
142 g_free (printer->ppd_name);
143 g_free (printer->default_cover_before);
144 g_free (printer->default_cover_after);
145 g_strfreev (printer->auth_info_required);
148 if (printer->colord_cancellable)
150 g_cancellable_cancel (printer->colord_cancellable);
151 g_object_unref (printer->colord_cancellable);
153 g_free (printer->colord_title);
154 g_free (printer->colord_qualifier);
155 if (printer->colord_client)
156 g_object_unref (printer->colord_client);
157 if (printer->colord_device)
158 g_object_unref (printer->colord_device);
159 if (printer->colord_profile)
160 g_object_unref (printer->colord_profile);
163 #ifdef HAVE_AVAHI_BROWSING
164 g_free (printer->avahi_name);
165 g_free (printer->avahi_type);
166 g_free (printer->avahi_domain);
169 if (printer->ppd_file)
170 ppdClose (printer->ppd_file);
172 if (printer->get_remote_ppd_poll > 0)
173 g_source_remove (printer->get_remote_ppd_poll);
174 printer->get_remote_ppd_attempts = 0;
176 gtk_cups_connection_test_free (printer->remote_cups_connection_test);
178 G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
182 gtk_printer_cups_set_property (GObject *object,
190 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
196 gtk_printer_cups_get_property (GObject *object,
202 GtkPrinterCups *printer = GTK_PRINTER_CUPS (object);
207 case PROP_PROFILE_TITLE:
209 if (printer->colord_title)
210 g_value_set_string (value, printer->colord_title);
212 g_value_set_static_string (value, "");
214 g_value_set_static_string (value, NULL);
218 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
226 colord_update_ui_from_settings (GtkPrinterCups *printer)
228 const gchar *title = NULL;
230 /* not yet connected to colord */
231 if (printer->colord_client == NULL)
233 if (!cd_client_get_connected (printer->colord_client))
236 /* failed to get a colord device for the printer */
237 if (printer->colord_device == NULL)
239 /* TRANSLATORS: when we're running an old CUPS, and
240 * it hasn't registered the device with colord */
241 title = _("Color management unavailable");
245 /* when colord prevents us from connecting (should not happen) */
246 if (!cd_device_get_connected (printer->colord_device))
249 /* failed to get a colord device for the printer */
250 if (printer->colord_profile == NULL)
252 /* TRANSLATORS: when there is no color profile available */
253 title = _("No profile available");
257 /* when colord prevents us from connecting (should not happen) */
258 if (!cd_profile_get_connected (printer->colord_profile))
260 title = cd_profile_get_title (printer->colord_profile);
263 /* TRANSLATORS: when the color profile has no title */
264 title = _("Unspecified profile");
270 if (g_strcmp0 (title, printer->colord_title) != 0)
272 g_free (printer->colord_title);
273 printer->colord_title = g_strdup (title);
274 g_object_notify (G_OBJECT (printer), "profile-title");
280 colord_client_profile_connect_cb (GObject *source_object,
285 GError *error = NULL;
286 GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
288 ret = cd_profile_connect_finish (CD_PROFILE (source_object),
293 g_warning ("failed to get properties from the profile: %s",
295 g_error_free (error);
299 colord_update_ui_from_settings (printer);
301 g_object_unref (printer);
305 colord_client_device_get_profile_for_qualifiers_cb (GObject *source_object,
309 GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
310 GError *error = NULL;
312 printer->colord_profile = cd_device_get_profile_for_qualifiers_finish (printer->colord_device,
315 if (printer->colord_profile == NULL)
317 /* not having a profile for a qualifier is not a warning */
318 g_debug ("no profile for device %s: %s",
319 cd_device_get_id (printer->colord_device),
321 g_error_free (error);
325 /* get details about the profile */
326 cd_profile_connect (printer->colord_profile,
327 printer->colord_cancellable,
328 colord_client_profile_connect_cb,
329 g_object_ref (printer));
332 colord_update_ui_from_settings (printer);
334 g_object_unref (printer);
338 gtk_printer_cups_update_settings (GtkPrinterCups *printer,
339 GtkPrintSettings *settings,
340 GtkPrinterOptionSet *set)
342 gchar *qualifier = NULL;
343 gchar **qualifiers = NULL;
344 GtkPrinterOption *option;
345 const gchar *format[3];
347 /* nothing set yet */
348 if (printer->colord_device == NULL)
350 if (!cd_device_get_connected (printer->colord_device))
353 /* cupsICCQualifier1 */
354 option = gtk_printer_option_set_lookup (set, "cups-ColorSpace");
356 option = gtk_printer_option_set_lookup (set, "cups-ColorModel");
358 format[0] = option->value;
362 /* cupsICCQualifier2 */
363 option = gtk_printer_option_set_lookup (set, "cups-OutputMode");
365 format[1] = option->value;
369 /* cupsICCQualifier3 */
370 option = gtk_printer_option_set_lookup (set, "cups-Resolution");
372 format[2] = option->value;
376 /* get profile for the device given the qualifier */
377 qualifier = g_strdup_printf ("%s.%s.%s,%s.%s.*,%s.*.*",
378 format[0], format[1], format[2],
379 format[0], format[1],
382 /* only requery colord if the option that was changed would give
383 * us a different profile result */
384 if (g_strcmp0 (qualifier, printer->colord_qualifier) == 0)
387 qualifiers = g_strsplit (qualifier, ",", -1);
388 cd_device_get_profile_for_qualifiers (printer->colord_device,
389 (const gchar **) qualifiers,
390 printer->colord_cancellable,
391 colord_client_device_get_profile_for_qualifiers_cb,
392 g_object_ref (printer));
394 /* save for the future */
395 g_free (printer->colord_qualifier);
396 printer->colord_qualifier = g_strdup (qualifier);
399 colord_update_ui_from_settings (printer);
402 g_strfreev (qualifiers);
406 colord_client_device_connect_cb (GObject *source_object,
410 GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
412 GError *error = NULL;
414 /* get details about the device */
415 ret = cd_device_connect_finish (CD_DEVICE (source_object), res, &error);
418 g_warning ("failed to get properties from the colord device: %s",
420 g_error_free (error);
425 colord_update_ui_from_settings (printer);
427 g_object_unref (printer);
431 colord_client_find_device_cb (GObject *source_object,
435 GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
436 GError *error = NULL;
438 /* get the new device */
439 printer->colord_device = cd_client_find_device_finish (printer->colord_client,
442 if (printer->colord_device == NULL)
444 g_warning ("failed to get find a colord device: %s",
446 g_error_free (error);
450 /* get details about the device */
451 g_cancellable_reset (printer->colord_cancellable);
452 cd_device_connect (printer->colord_device,
453 printer->colord_cancellable,
454 colord_client_device_connect_cb,
455 g_object_ref (printer));
458 colord_update_ui_from_settings (printer);
460 g_object_unref (printer);
464 colord_update_device (GtkPrinterCups *printer)
466 gchar *colord_device_id = NULL;
468 /* not yet connected to the daemon */
469 if (!cd_client_get_connected (printer->colord_client))
472 /* not yet assigned a printer */
473 if (printer->ppd_file == NULL)
476 /* old cached profile no longer valid */
477 if (printer->colord_profile)
479 g_object_unref (printer->colord_profile);
480 printer->colord_profile = NULL;
483 /* old cached device no longer valid */
484 if (printer->colord_device)
486 g_object_unref (printer->colord_device);
487 printer->colord_device = NULL;
490 /* generate a known ID */
491 colord_device_id = g_strdup_printf ("cups-%s", gtk_printer_get_name (GTK_PRINTER (printer)));
493 g_cancellable_reset (printer->colord_cancellable);
494 cd_client_find_device (printer->colord_client,
496 printer->colord_cancellable,
497 colord_client_find_device_cb,
498 g_object_ref (printer));
500 g_free (colord_device_id);
503 colord_update_ui_from_settings (printer);
507 colord_client_connect_cb (GObject *source_object,
512 GError *error = NULL;
513 GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
515 ret = cd_client_connect_finish (CD_CLIENT (source_object),
519 g_warning ("failed to contact colord: %s", error->message);
520 g_error_free (error);
523 /* refresh the device */
524 colord_update_device (printer);
526 g_object_unref (printer);
530 colord_printer_details_aquired_cb (GtkPrinterCups *printer,
534 /* refresh the device */
535 if (printer->colord_client)
536 colord_update_device (printer);
541 * gtk_printer_cups_new:
543 * Creates a new #GtkPrinterCups.
545 * Return value: a new #GtkPrinterCups
550 gtk_printer_cups_new (const char *name,
551 GtkPrintBackend *backend,
552 gpointer colord_client)
555 gboolean accepts_pdf;
556 GtkPrinterCups *printer;
558 #if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
564 result = g_object_new (GTK_TYPE_PRINTER_CUPS,
568 "accepts-pdf", accepts_pdf,
570 printer = GTK_PRINTER_CUPS (result);
573 /* connect to colord */
574 if (colord_client != NULL)
576 printer->colord_cancellable = g_cancellable_new ();
577 printer->colord_client = g_object_ref (CD_CLIENT (colord_client));
578 cd_client_connect (printer->colord_client,
579 printer->colord_cancellable,
580 colord_client_connect_cb,
581 g_object_ref (printer));
584 /* update the device when we read the PPD */
585 g_signal_connect (printer, "details-acquired",
586 G_CALLBACK (colord_printer_details_aquired_cb),
591 * IPP version 1.1 has to be supported
592 * by all implementations according to rfc 2911
594 printer->ipp_version_major = 1;
595 printer->ipp_version_minor = 1;
601 gtk_printer_cups_get_ppd (GtkPrinterCups *printer)
603 return printer->ppd_file;
607 gtk_printer_cups_get_ppd_name (GtkPrinterCups *printer)
611 result = printer->ppd_name;
614 result = gtk_printer_get_name (GTK_PRINTER (printer));