#include "gtkcupsutils.h"
+#ifdef HAVE_COLORD
+#include <colord.h>
+#endif
typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass;
GHashTable *auth;
gchar *username;
gboolean authentication_lock;
+#ifdef HAVE_COLORD
+ CdClient *colord_client;
+#endif
};
static GObjectClass *backend_parent_class;
backend_cups->username = NULL;
+#ifdef HAVE_COLORD
+ backend_cups->colord_client = cd_client_new ();
+#endif
+
cups_get_local_default_printer (backend_cups);
}
g_free (backend_cups->username);
+#ifdef HAVE_COLORD
+ g_object_unref (backend_cups->colord_client);
+#endif
+
backend_parent_class->finalize (object);
}
char *cups_server; /* CUPS server */
list_has_changed = TRUE;
- cups_printer = gtk_printer_cups_new (printer_name, backend);
+#ifdef HAVE_COLORD
+ cups_printer = gtk_printer_cups_new (printer_name,
+ backend,
+ cups_backend->colord_client);
+#else
+ cups_printer = gtk_printer_cups_new (printer_name, backend, NULL);
+#endif
cups_printer->device_uri = g_strdup_printf ("/printers/%s", printer_name);
}
+#ifdef HAVE_COLORD
+
+typedef struct {
+ GtkPrintSettings *settings;
+ GtkPrinter *printer;
+} GtkPrintBackendCupsColordHelper;
+
+static void
+colord_printer_option_set_changed_cb (GtkPrinterOptionSet *set,
+ GtkPrintBackendCupsColordHelper *helper)
+{
+ gtk_printer_cups_update_settings (GTK_PRINTER_CUPS (helper->printer),
+ helper->settings,
+ set);
+}
+#endif
+
static GtkPrinterOptionSet *
cups_printer_get_options (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPrintBackendCups *backend;
GtkTextDirection text_direction;
GtkPrinterCups *cups_printer = NULL;
-
+#ifdef HAVE_COLORD
+ GtkPrintBackendCupsColordHelper *helper;
+#endif
set = gtk_printer_option_set_new ();
cupsFreeOptions (num_opts, opts);
+#ifdef HAVE_COLORD
+ /* TRANSLATORS: this this the ICC color profile to use for this job */
+ option = gtk_printer_option_new ("colord-profile",
+ _("Printer Profile"),
+ GTK_PRINTER_OPTION_TYPE_INFO);
+
+ /* assign it to the color page */
+ option->group = g_strdup ("ColorPage");
+
+ /* TRANSLATORS: this is when color profile information is unavailable */
+ gtk_printer_option_set (option, _("Unavailable"));
+ gtk_printer_option_set_add (set, option);
+
+ /* watch to see if the user changed the options */
+ helper = g_new (GtkPrintBackendCupsColordHelper, 1);
+ helper->printer = printer;
+ helper->settings = settings;
+ g_signal_connect_data (set, "changed",
+ G_CALLBACK (colord_printer_option_set_changed_cb),
+ helper,
+ (GClosureNotify) g_free,
+ 0);
+
+ /* initial coldplug */
+ gtk_printer_cups_update_settings (GTK_PRINTER_CUPS (printer),
+ settings, set);
+ g_object_bind_property (printer, "profile-title",
+ option, "value",
+ G_BINDING_DEFAULT);
+
+#endif
+
return set;
}
/* GtkPrinterCupsCups
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
+ * Copyright (C) 2011 Richard Hughes <rhughes@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*/
#include "config.h"
+
+#include <glib/gi18n-lib.h>
+
+#ifdef HAVE_COLORD
+#include <colord.h>
+#endif
+
+#include "gtkintl.h"
#include "gtkprintercups.h"
+enum {
+ PROP_0,
+ PROP_PROFILE_TITLE
+};
+
static void gtk_printer_cups_init (GtkPrinterCups *printer);
static void gtk_printer_cups_class_init (GtkPrinterCupsClass *class);
static void gtk_printer_cups_finalize (GObject *object);
static GtkPrinterClass *gtk_printer_cups_parent_class;
static GType gtk_printer_cups_type = 0;
+static void gtk_printer_cups_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_printer_cups_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
void
gtk_printer_cups_register_type (GTypeModule *module)
{
gtk_printer_cups_class_init (GtkPrinterCupsClass *class)
{
GObjectClass *object_class = (GObjectClass *) class;
-
- gtk_printer_cups_parent_class = g_type_class_peek_parent (class);
object_class->finalize = gtk_printer_cups_finalize;
+ object_class->set_property = gtk_printer_cups_set_property;
+ object_class->get_property = gtk_printer_cups_get_property;
+
+ gtk_printer_cups_parent_class = g_type_class_peek_parent (class);
+
+ g_object_class_install_property (G_OBJECT_CLASS (class),
+ PROP_PROFILE_TITLE,
+ g_param_spec_string ("profile-title",
+ P_("Color Profile Title"),
+ P_("The title of the color profile to use"),
+ "",
+ G_PARAM_READABLE));
}
static void
g_free (printer->default_cover_after);
g_strfreev (printer->auth_info_required);
+#ifdef HAVE_COLORD
+ g_cancellable_cancel (printer->colord_cancellable);
+ g_object_unref (printer->colord_cancellable);
+ g_free (printer->colord_title);
+ g_free (printer->colord_qualifier);
+ if (printer->colord_client)
+ g_object_unref (printer->colord_client);
+ if (printer->colord_device)
+ g_object_unref (printer->colord_device);
+ if (printer->colord_profile)
+ g_object_unref (printer->colord_profile);
+#endif
+
if (printer->ppd_file)
ppdClose (printer->ppd_file);
G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
}
+static void
+gtk_printer_cups_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_printer_cups_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkPrinterCups *printer = GTK_PRINTER_CUPS (object);
+
+ switch (prop_id)
+ {
+ case PROP_PROFILE_TITLE:
+#ifdef HAVE_COLORD
+ if (printer->colord_title)
+ g_value_set_string (value, printer->colord_title);
+ else
+ g_value_set_static_string (value, "");
+#else
+ g_value_set_static_string (value, NULL);
+#endif
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+#ifdef HAVE_COLORD
+
+static void
+colord_update_ui_from_settings (GtkPrinterCups *printer)
+{
+ const gchar *title = NULL;
+
+ /* not yet connected to colord */
+ if (printer->colord_client == NULL)
+ goto out;
+ if (!cd_client_get_connected (printer->colord_client))
+ goto out;
+
+ /* failed to get a colord device for the printer */
+ if (printer->colord_device == NULL)
+ {
+ /* TRANSLATORS: when we're running an old CUPS, and
+ * it hasn't registered the device with colord */
+ title = _("Color management unavailable");
+ goto out;
+ }
+
+ /* when colord prevents us from connecting (should not happen) */
+ if (!cd_device_get_connected (printer->colord_device))
+ goto out;
+
+ /* failed to get a colord device for the printer */
+ if (printer->colord_profile == NULL)
+ {
+ /* TRANSLATORS: when there is no color profile available */
+ title = _("No profile available");
+ goto out;
+ }
+
+ /* when colord prevents us from connecting (should not happen) */
+ if (!cd_profile_get_connected (printer->colord_profile))
+ goto out;
+ title = cd_profile_get_title (printer->colord_profile);
+ if (title == NULL)
+ {
+ /* TRANSLATORS: when the color profile has no title */
+ title = _("Unspecified profile");
+ goto out;
+ }
+
+out:
+ /* SUCCESS! */
+ if (g_strcmp0 (title, printer->colord_title) != 0)
+ {
+ g_free (printer->colord_title);
+ printer->colord_title = g_strdup (title);
+ g_object_notify (G_OBJECT (printer), "profile-title");
+ }
+ return;
+}
+
+static void
+colord_client_profile_connect_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ gboolean ret;
+ GError *error = NULL;
+ GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
+
+ ret = cd_profile_connect_finish (CD_PROFILE (source_object),
+ res,
+ &error);
+ if (!ret)
+ {
+ g_warning ("failed to get properties from the profile: %s",
+ error->message);
+ g_error_free (error);
+ }
+
+ /* update the UI */
+ colord_update_ui_from_settings (printer);
+}
+
+static void
+colord_client_device_get_profile_for_qualifiers_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
+ GError *error = NULL;
+
+ printer->colord_profile = cd_device_get_profile_for_qualifiers_finish (printer->colord_device,
+ res,
+ &error);
+ if (printer->colord_profile == NULL)
+ {
+ /* not having a profile for a qualifier is not a warning */
+ g_debug ("no profile for device %s: %s",
+ cd_device_get_id (printer->colord_device),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get details about the profile */
+ cd_profile_connect (printer->colord_profile,
+ printer->colord_cancellable,
+ colord_client_profile_connect_cb,
+ printer);
+out:
+ /* update the UI */
+ colord_update_ui_from_settings (printer);
+}
+
+void
+gtk_printer_cups_update_settings (GtkPrinterCups *printer,
+ GtkPrintSettings *settings,
+ GtkPrinterOptionSet *set)
+{
+ gchar *qualifier = NULL;
+ gchar **qualifiers = NULL;
+ GtkPrinterOption *option;
+ const gchar *format[3];
+
+ /* nothing set yet */
+ if (printer->colord_device == NULL)
+ goto out;
+ if (!cd_device_get_connected (printer->colord_device))
+ goto out;
+
+ /* cupsICCQualifier1 */
+ option = gtk_printer_option_set_lookup (set, "cups-ColorSpace");
+ if (option == NULL)
+ option = gtk_printer_option_set_lookup (set, "cups-ColorModel");
+ if (option != NULL)
+ format[0] = option->value;
+ else
+ format[0] = "*";
+
+ /* cupsICCQualifier2 */
+ option = gtk_printer_option_set_lookup (set, "cups-OutputMode");
+ if (option != NULL)
+ format[1] = option->value;
+ else
+ format[1] = "*";
+
+ /* cupsICCQualifier3 */
+ option = gtk_printer_option_set_lookup (set, "cups-Resolution");
+ if (option != NULL)
+ format[2] = "*";
+
+ /* get profile for the device given the qualifier */
+ qualifier = g_strdup_printf ("%s.%s.%s,%s.%s.*,%s.*.*",
+ format[0], format[1], format[2],
+ format[0], format[1],
+ format[0]);
+
+ /* only requery colord if the option that was changed would give
+ * us a different profile result */
+ if (g_strcmp0 (qualifier, printer->colord_qualifier) == 0)
+ goto out;
+
+ qualifiers = g_strsplit (qualifier, ",", -1);
+ cd_device_get_profile_for_qualifiers (printer->colord_device,
+ (const gchar **) qualifiers,
+ printer->colord_cancellable,
+ colord_client_device_get_profile_for_qualifiers_cb,
+ printer);
+
+ /* save for the future */
+ g_free (printer->colord_qualifier);
+ printer->colord_qualifier = g_strdup (qualifier);
+
+ /* update the UI */
+ colord_update_ui_from_settings (printer);
+out:
+ g_free (qualifier);
+ g_strfreev (qualifiers);
+}
+
+static void
+colord_client_device_connect_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
+ gboolean ret;
+ GError *error = NULL;
+
+ /* get details about the device */
+ ret = cd_device_connect_finish (CD_DEVICE (source_object), res, &error);
+ if (!ret)
+ {
+ g_warning ("failed to get properties from the colord device: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ /* update the UI */
+ colord_update_ui_from_settings (printer);
+}
+
+static void
+colord_client_find_device_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
+ GError *error = NULL;
+
+ /* get the new device */
+ printer->colord_device = cd_client_find_device_finish (printer->colord_client,
+ res,
+ &error);
+ if (printer->colord_device == NULL)
+ {
+ g_warning ("failed to get find a colord device: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get details about the device */
+ g_cancellable_reset (printer->colord_cancellable);
+ cd_device_connect (printer->colord_device,
+ printer->colord_cancellable,
+ colord_client_device_connect_cb,
+ printer);
+out:
+ /* update the UI */
+ colord_update_ui_from_settings (printer);
+}
+
+static void
+colord_update_device (GtkPrinterCups *printer)
+{
+ gchar *colord_device_id = NULL;
+
+ /* not yet connected to the daemon */
+ if (!cd_client_get_connected (printer->colord_client))
+ goto out;
+
+ /* not yet assigned a printer */
+ if (printer->ppd_file == NULL)
+ goto out;
+
+ /* old cached profile no longer valid */
+ if (printer->colord_profile)
+ {
+ g_object_unref (printer->colord_profile);
+ printer->colord_profile = NULL;
+ }
+
+ /* old cached device no longer valid */
+ if (printer->colord_device)
+ {
+ g_object_unref (printer->colord_device);
+ printer->colord_device = NULL;
+ }
+
+ /* generate a known ID */
+ colord_device_id = g_strdup_printf ("cups-%s", gtk_printer_get_name (GTK_PRINTER (printer)));
+
+ g_cancellable_reset (printer->colord_cancellable);
+ cd_client_find_device (printer->colord_client,
+ colord_device_id,
+ printer->colord_cancellable,
+ colord_client_find_device_cb,
+ printer);
+out:
+ g_free (colord_device_id);
+
+ /* update the UI */
+ colord_update_ui_from_settings (printer);
+}
+
+static void
+colord_client_connect_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ gboolean ret;
+ GError *error = NULL;
+ GtkPrinterCups *printer = GTK_PRINTER_CUPS (user_data);
+
+ ret = cd_client_connect_finish (CD_CLIENT (source_object),
+ res, &error);
+ if (!ret)
+ {
+ g_warning ("failed to contact colord: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* refresh the device */
+ colord_update_device (printer);
+}
+#endif
+
/**
* gtk_printer_cups_new:
*
**/
GtkPrinterCups *
gtk_printer_cups_new (const char *name,
- GtkPrintBackend *backend)
+ GtkPrintBackend *backend,
+ gpointer colord_client)
{
GObject *result;
gboolean accepts_pdf;
+ GtkPrinterCups *printer;
#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
accepts_pdf = TRUE;
"is-virtual", FALSE,
"accepts-pdf", accepts_pdf,
NULL);
+ printer = GTK_PRINTER_CUPS (result);
- return (GtkPrinterCups *) result;
+#ifdef HAVE_COLORD
+ /* connect to colord */
+ if (colord_client != NULL)
+ {
+ printer->colord_cancellable = g_cancellable_new ();
+ printer->colord_client = g_object_ref (CD_CLIENT (colord_client));
+ cd_client_connect (printer->colord_client,
+ printer->colord_cancellable,
+ colord_client_connect_cb,
+ printer);
+ }
+#endif
+ return printer;
}
ppd_file_t *