X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=modules%2Fprintbackends%2Fcups%2Fgtkprintercups.c;h=cc1c5774ba2e971d10c8f3d3b82c9d67facf495d;hb=e0d32d9456e1b15c64e8b9863189c04040948d5e;hp=09818c35050ed289f69655d57e2e5af432671d08;hpb=37255486d4c4ef49d784e5383b3181e70b048474;p=~andy%2Fgtk diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index 09818c350..cc1c5774b 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -1,5 +1,6 @@ /* GtkPrinterCupsCups * Copyright (C) 2006 John (J5) Palmieri + * Copyright (C) 2011 Richard Hughes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,8 +19,21 @@ */ #include "config.h" + +#include + +#ifdef HAVE_COLORD +#include +#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); @@ -27,6 +41,15 @@ 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) { @@ -59,10 +82,20 @@ static void 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 @@ -101,6 +134,19 @@ gtk_printer_cups_finalize (GObject *object) 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); @@ -113,6 +159,345 @@ gtk_printer_cups_finalize (GObject *object) 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) +{ +#ifdef HAVE_COLORD + GtkPrinterCups *printer = GTK_PRINTER_CUPS (object); +#endif + + 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] = option->value; + else + 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: * @@ -124,17 +509,40 @@ gtk_printer_cups_finalize (GObject *object) **/ 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; +#else + accepts_pdf = FALSE; +#endif + result = g_object_new (GTK_TYPE_PRINTER_CUPS, "name", name, "backend", backend, "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 *