]> Pileus Git - ~andy/gtk/blobdiff - modules/printbackends/cups/gtkprintercups.c
cups: Fix unused variable warning when not using colord
[~andy/gtk] / modules / printbackends / cups / gtkprintercups.c
index 2a8a5355f41b183331dacf6cdf2131ee9e78caea..09b5bfd916ac167798b5cb2afb7c91dc3a04a0c5 100644 (file)
@@ -1,5 +1,6 @@
 /* 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);
@@ -27,10 +41,19 @@ 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)
 {
-  static const GTypeInfo object_info =
+  const GTypeInfo object_info =
   {
     sizeof (GtkPrinterCupsClass),
     (GBaseInitFunc) NULL,
@@ -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
@@ -73,7 +106,15 @@ gtk_printer_cups_init (GtkPrinterCups *printer)
   printer->state = 0;
   printer->hostname = NULL;
   printer->port = 0;
+  printer->ppd_name = NULL;
   printer->ppd_file = NULL;
+  printer->default_cover_before = NULL;
+  printer->default_cover_after = NULL;
+  printer->remote = FALSE;
+  printer->get_remote_ppd_poll = 0;
+  printer->get_remote_ppd_attempts = 0;
+  printer->remote_cups_connection_test = NULL;
+  printer->auth_info_required = NULL;
 }
 
 static void
@@ -88,13 +129,373 @@ gtk_printer_cups_finalize (GObject *object)
   g_free (printer->device_uri);
   g_free (printer->printer_uri);
   g_free (printer->hostname);
+  g_free (printer->ppd_name);
+  g_free (printer->default_cover_before);
+  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);
 
+  if (printer->get_remote_ppd_poll > 0)
+    g_source_remove (printer->get_remote_ppd_poll);
+  printer->get_remote_ppd_attempts = 0;
+
+  gtk_cups_connection_test_free (printer->remote_cups_connection_test);
+
   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] = "*";
+
+  /* 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:
  *
@@ -106,17 +507,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 *
@@ -124,3 +548,16 @@ gtk_printer_cups_get_ppd (GtkPrinterCups *printer)
 {
   return printer->ppd_file;
 }
+
+const gchar *
+gtk_printer_cups_get_ppd_name (GtkPrinterCups  *printer)
+{
+  const gchar *result;
+
+  result = printer->ppd_name;
+
+  if (result == NULL)
+    result = gtk_printer_get_name (GTK_PRINTER (printer));
+
+  return result;
+}