Richard Hughes e9e839c
--- a/scheduler/Makefile
Richard Hughes e9e839c
+++ b/scheduler/Makefile
Richard Hughes e9e839c
@@ -26,6 +26,7 @@ CUPSDOBJS =	\
Richard Hughes e9e839c
 		env.o \
Richard Hughes e9e839c
 		main.o \
Richard Hughes e9e839c
 		ipp.o \
Richard Hughes e9e839c
+		colord.o \
Richard Hughes e9e839c
 		listen.o \
Richard Hughes e9e839c
 		job.o \
Richard Hughes e9e839c
 		log.o \
2b082bd
--- b/scheduler/colord.c
2b082bd
+++ cups-1.4.6/scheduler/colord.c	2011-05-24 12:47:19.698093377 +0100
2b082bd
@@ -0,0 +1,684 @@
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * "$Id$"
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   colord integration for the CUPS scheduler.
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   Copyright 2011, Red Hat.
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   These coded instructions, statements, and computer programs are the
Richard Hughes e9e839c
+ *   property of Apple Inc. and are protected by Federal copyright
Richard Hughes e9e839c
+ *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
Richard Hughes e9e839c
+ *   which should have been included with this file.  If this file is
Richard Hughes e9e839c
+ *   file is missing or damaged, see the license at "http://www.cups.org/".
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ * Contents:
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   colordRegisterPrinter()    - Register profiles for a printer.
Richard Hughes e9e839c
+ *   colordUnregisterPrinter()  - Unregister profiles for a printer.
Richard Hughes e9e839c
+ *   colordStart()              - Get a connection to the system bus.
Richard Hughes e9e839c
+ *   colordStop()               - Release any connection to the system bus
Richard Hughes e9e839c
+ *                                so that added profiles and devices are
Richard Hughes e9e839c
+ *                                automatically removed.
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * Include necessary headers...
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+#include "cupsd.h"
ba9bc8e
+
ba9bc8e
+#ifdef HAVE_DBUS
ba9bc8e
+
Richard Hughes e9e839c
+#include <dbus/dbus.h>
Richard Hughes e9e839c
+#include <cups/ppd-private.h>
ba9bc8e
+
ba9bc8e
+/*
Richard Hughes e9e839c
+ * Defines used by colord. See the reference docs for further details:
Richard Hughes e9e839c
+ * http://colord.hughsie.com/api/ref-dbus.html
ba9bc8e
+ */
Richard Hughes e9e839c
+#define COLORD_SCOPE_NORMAL   "normal"    /* System scope */
Richard Hughes e9e839c
+#define COLORD_SCOPE_TEMP     "temp"      /* Process scope */
Richard Hughes e9e839c
+#define COLORD_SCOPE_DISK     "disk"      /* Lives forever, as stored in DB */
ba9bc8e
+
Richard Hughes e9e839c
+#define COLORD_RELATION_SOFT  "soft"      /* Mapping is not default */
Richard Hughes e9e839c
+#define COLORD_RELATION_HARD  "hard"      /* Explicitly mapped profile */
ba9bc8e
+
Richard Hughes e9e839c
+#define COLORD_SPACE_RGB      "rgb"       /* RGB colorspace */
Richard Hughes e9e839c
+#define COLORD_SPACE_CMYK     "cmyk"      /* CMYK colorspace */
Richard Hughes c444f44
+#define COLORD_SPACE_GRAY     "gray"      /* Gray colorspace */
Richard Hughes 46d60c6
+#define COLORD_SPACE_UNKNOWN  "unknown"   /* Unknown colorspace */
ba9bc8e
+
Richard Hughes e9e839c
+#define COLORD_MODE_PHYSICAL  "physical"  /* Actual device */
Richard Hughes e9e839c
+#define COLORD_MODE_VIRTUAL   "virtual"   /* Virtual device with no hardware */
ba9bc8e
+
Richard Hughes e9e839c
+#define COLORD_KIND_PRINTER   "printer"   /* printing output device */
ba9bc8e
+
Richard Hughes c444f44
+/* the timeout for connecting to colord */
Richard Hughes c444f44
+#define COLORD_DBUS_TIMEOUT   5000        /* ms */
Richard Hughes c444f44
+
Richard Hughes e9e839c
+/* This is static */
Richard Hughes e9e839c
+static DBusConnection *con = NULL;
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'colordStart()' - Get a connection to the system bus.
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+void
Richard Hughes e9e839c
+colordStart(void)
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+  if (con)
Richard Hughes e9e839c
+    return;
Richard Hughes e9e839c
+  con = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
ba9bc8e
+}
ba9bc8e
+
ba9bc8e
+/*
Richard Hughes e9e839c
+ * 'colordStop()' - Release any connection to the system bus so that
Richard Hughes e9e839c
+ *                  added profiles and devices are automatically removed.
c45b42d
+ */
c45b42d
+
Richard Hughes e9e839c
+void
Richard Hughes e9e839c
+colordStop(void)
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+  if (con == NULL)
Richard Hughes e9e839c
+    return;
Richard Hughes e9e839c
+  dbus_connection_unref(con);
Richard Hughes e9e839c
+  con = NULL;
c45b42d
+}
c45b42d
+
c45b42d
+/*
Richard Hughes e9e839c
+ * 'message_dict_add_strings()' - add two strings to a dictionary.
ba9bc8e
+ */
Richard Hughes e9e839c
+
c45b42d
+static void
Richard Hughes e9e839c
+message_dict_add_strings (DBusMessageIter *dict,
Richard Hughes e9e839c
+                          const char *key,
Richard Hughes e9e839c
+                          const char *value)
c45b42d
+{
Richard Hughes e9e839c
+        DBusMessageIter entry;
Richard Hughes e9e839c
+        dbus_message_iter_open_container(dict,
Richard Hughes e9e839c
+                                         DBUS_TYPE_DICT_ENTRY,
Richard Hughes e9e839c
+                                         NULL,
Richard Hughes e9e839c
+                                         &entry);
Richard Hughes e9e839c
+        dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
Richard Hughes e9e839c
+        dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &value);
Richard Hughes e9e839c
+        dbus_message_iter_close_container(dict, &entry);
c45b42d
+}
c45b42d
+
c45b42d
+/*
Richard Hughes e9e839c
+ * 'colordCreateProfile()' - Create a color profile for a printer.
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ * Notes: When creating the device, we can create
c45b42d
+ */
Richard Hughes e9e839c
+
ba9bc8e
+static void
Richard Hughes e9e839c
+colordCreateProfile (cups_array_t *profiles,    /* I - Profiles array */
Richard Hughes e9e839c
+                     const char *printer_name,  /* I - Printer name */
Richard Hughes e9e839c
+                     const char *qualifier,     /* I - Profile qualifier */
Richard Hughes 46d60c6
+                     const char *colorspace,    /* I - Profile colorspace */
Richard Hughes e9e839c
+                     const char **format,       /* I - Profile qualifier format */
Richard Hughes e9e839c
+                     const char *iccfile,       /* I - ICC filename */
Richard Hughes e9e839c
+                     const char *scope)         /* I - The scope of the profile, e.g.
Richard Hughes e9e839c
+                                                       'normal', 'temp' or 'disk' */
ba9bc8e
+{
Richard Hughes e9e839c
+  DBusMessage           *message = NULL;        /* D-Bus request */
Richard Hughes e9e839c
+  DBusMessage           *reply = NULL;          /* D-Bus reply */
Richard Hughes e9e839c
+  DBusMessageIter       args;                   /* D-Bus method arguments */
Richard Hughes e9e839c
+  DBusMessageIter       dict;                   /* D-Bus method arguments */
Richard Hughes e9e839c
+  DBusError             error;                  /* D-Bus error */
Richard Hughes e9e839c
+  char                  *idstr;                 /* Profile ID string */
Richard Hughes e9e839c
+  size_t                idstrlen;               /* Profile ID allocated length */
Richard Hughes e9e839c
+  const char            *profile_path;          /* Device object path */
Richard Hughes e9e839c
+  char                  format_str[1024];       /* Qualifier format as a string */
ba9bc8e
+
ba9bc8e
+ /*
ba9bc8e
+  * Create the profile...
ba9bc8e
+  */
ba9bc8e
+
ba9bc8e
+  message = dbus_message_new_method_call("org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         "/org/freedesktop/ColorManager",
Richard Hughes e9e839c
+                                         "org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         "CreateProfile");
ba9bc8e
+
Richard Hughes e9e839c
+  /* create a profile id */
ba9bc8e
+  idstrlen = strlen (printer_name) + 1 + strlen (qualifier) + 1;
ba9bc8e
+  idstr = malloc (idstrlen);
ba9bc8e
+  if (!idstr)
ba9bc8e
+      goto out;
ba9bc8e
+  snprintf (idstr, idstrlen, "%s-%s", printer_name, qualifier);
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Using profile id of %s",
Richard Hughes e9e839c
+                  idstr);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  dbus_message_iter_init_append(message, &args);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &idstr);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* mush the qualifier format into a simple string */
Richard Hughes e9e839c
+  snprintf(format_str, sizeof(format_str), "%s.%s.%s",
Richard Hughes e9e839c
+           format[0],
Richard Hughes e9e839c
+           format[1],
Richard Hughes e9e839c
+           format[2]);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* set initial properties */
Richard Hughes e9e839c
+  dbus_message_iter_open_container(&args,
Richard Hughes e9e839c
+                                   DBUS_TYPE_ARRAY,
Richard Hughes e9e839c
+                                   "{ss}",
Richard Hughes e9e839c
+                                   &dict);
Richard Hughes e9e839c
+  message_dict_add_strings(&dict, "Qualifier", qualifier);
Richard Hughes e9e839c
+  message_dict_add_strings(&dict, "Format", format_str);
Richard Hughes 46d60c6
+  message_dict_add_strings(&dict, "Colorspace", colorspace);
Richard Hughes e9e839c
+  if (iccfile != NULL)
Richard Hughes e9e839c
+    message_dict_add_strings(&dict, "Filename", iccfile);
Richard Hughes e9e839c
+  dbus_message_iter_close_container(&args, &dict);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* send syncronous */
Richard Hughes e9e839c
+  dbus_error_init(&error);
Richard Hughes c444f44
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateProfile(%s,%s)",
Richard Hughes c444f44
+                  idstr, scope);
Richard Hughes e9e839c
+  reply = dbus_connection_send_with_reply_and_block(con,
Richard Hughes e9e839c
+                                                    message,
Richard Hughes c444f44
+                                                    COLORD_DBUS_TIMEOUT,
Richard Hughes e9e839c
+                                                    &error);
Richard Hughes e9e839c
+  if (reply == NULL)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+        cupsdLogMessage(CUPSD_LOG_WARN,
Richard Hughes e9e839c
+                        "failed to CreateProfile: %s:%s",
Richard Hughes e9e839c
+                        error.name, error.message);
Richard Hughes e9e839c
+        dbus_error_free(&error);
Richard Hughes e9e839c
+        goto out;
Richard Hughes e9e839c
+  }
ba9bc8e
+
Richard Hughes e9e839c
+  /* get reply data */
Richard Hughes e9e839c
+  dbus_message_iter_init(reply, &args);
Richard Hughes e9e839c
+  if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+        cupsdLogMessage(CUPSD_LOG_WARN,
Richard Hughes e9e839c
+                        "incorrect reply type");
Richard Hughes e9e839c
+        goto out;
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  dbus_message_iter_get_basic(&args, &profile_path);
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
Richard Hughes e9e839c
+                  "created profile %s",
Richard Hughes e9e839c
+                  profile_path);
Richard Hughes e9e839c
+  cupsArrayAdd(profiles, strdup(profile_path));
ba9bc8e
+
ba9bc8e
+out:
Richard Hughes e9e839c
+  if (message != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(message);
Richard Hughes e9e839c
+  if (reply != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(reply);
ba9bc8e
+  free (idstr);
ba9bc8e
+}
ba9bc8e
+
ba9bc8e
+/*
Richard Hughes e9e839c
+ * 'colordDeviceAddProfile()' - Assign a profile to a device.
ba9bc8e
+ */
ba9bc8e
+
ba9bc8e
+static void
Richard Hughes e9e839c
+colordDeviceAddProfile (const char *device_path,       /* I - Device object path */
Richard Hughes e9e839c
+                        const char *profile_path,      /* I - Profile object path */
Richard Hughes e9e839c
+                        const char *relation)          /* I - Device relation, either 'soft' or 'hard' */
ba9bc8e
+{
Richard Hughes e9e839c
+  DBusMessage           *message = NULL;        /* D-Bus request */
Richard Hughes e9e839c
+  DBusMessage           *reply = NULL;          /* D-Bus reply */
Richard Hughes e9e839c
+  DBusMessageIter       args;                   /* D-Bus method arguments */
Richard Hughes e9e839c
+  DBusError             error;                  /* D-Bus error */
ba9bc8e
+
ba9bc8e
+  message = dbus_message_new_method_call("org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         device_path,
Richard Hughes e9e839c
+                                         "org.freedesktop.ColorManager.Device",
Richard Hughes e9e839c
+                                         "AddProfile");
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* send profile path as the argument */
Richard Hughes e9e839c
+  dbus_message_iter_init_append(message, &args);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &relation);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &profile_path);
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
Richard Hughes e9e839c
+                  "Calling %s:AddProfile(%s) [%s]",
Richard Hughes e9e839c
+                  device_path, profile_path, relation);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* send syncronous */
Richard Hughes e9e839c
+  dbus_error_init(&error);
Richard Hughes e9e839c
+  reply = dbus_connection_send_with_reply_and_block(con,
Richard Hughes e9e839c
+                                                    message,
Richard Hughes c444f44
+                                                    COLORD_DBUS_TIMEOUT,
Richard Hughes e9e839c
+                                                    &error);
Richard Hughes e9e839c
+  if (reply == NULL)
ba9bc8e
+  {
Richard Hughes e9e839c
+        cupsdLogMessage(CUPSD_LOG_WARN,
Richard Hughes e9e839c
+                        "failed to AddProfile: %s:%s",
Richard Hughes e9e839c
+                        error.name, error.message);
Richard Hughes e9e839c
+        dbus_error_free(&error);
Richard Hughes e9e839c
+        goto out;
ba9bc8e
+  }
Richard Hughes e9e839c
+out:
Richard Hughes e9e839c
+  if (message != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(message);
Richard Hughes e9e839c
+  if (reply != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(reply);
Richard Hughes e9e839c
+}
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'colordCreateDevice()' - Create a device and register profiles.
Richard Hughes e9e839c
+ */
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+static void
Richard Hughes e9e839c
+colordCreateDevice (cupsd_printer_t *p,         /* I - Printer */
Richard Hughes c444f44
+                    ppd_file_t *ppd,            /* I - PPD file */
Richard Hughes e9e839c
+                    cups_array_t *profiles,     /* I - Profiles array */
Richard Hughes e9e839c
+                    const char *colorspace,     /* I - Device colorspace, e.g. 'rgb' */
Richard Hughes e9e839c
+                    const char *relation,       /* I - Profile relation, either 'soft' or 'hard' */
Richard Hughes e9e839c
+                    const char *scope)          /* I - The scope of the device, e.g.
Richard Hughes e9e839c
+                                                       'normal', 'temp' or 'disk' */
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+  DBusMessage           *message = NULL;        /* D-Bus request */
Richard Hughes e9e839c
+  DBusMessage           *reply = NULL;          /* D-Bus reply */
Richard Hughes e9e839c
+  DBusMessageIter       args;                   /* D-Bus method arguments */
Richard Hughes e9e839c
+  DBusMessageIter       dict;                   /* D-Bus method arguments */
Richard Hughes e9e839c
+  DBusError             error;                  /* D-Bus error */
Richard Hughes e9e839c
+  const char            *device_path;           /* Device object path */
Richard Hughes e9e839c
+  const char            *profile_path;          /* Profile path */
Richard Hughes e9e839c
+  char                  *default_profile_path = NULL;
Richard Hughes e9e839c
+                                                /* Default profile path */
Richard Hughes e9e839c
+  char                  device_id[1024];        /* Device ID as understood by colord */
ba9bc8e
+
ba9bc8e
+ /*
Richard Hughes e9e839c
+  * Create the device...
ba9bc8e
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
Richard Hughes e9e839c
+  device_path = device_id;
ba9bc8e
+
Richard Hughes e9e839c
+  message = dbus_message_new_method_call("org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         "/org/freedesktop/ColorManager",
Richard Hughes e9e839c
+                                         "org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         "CreateDevice");
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  dbus_message_iter_init_append(message, &args);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_path);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* set initial properties */
Richard Hughes e9e839c
+  dbus_message_iter_open_container(&args,
Richard Hughes e9e839c
+                                 DBUS_TYPE_ARRAY,
Richard Hughes e9e839c
+                                 "{ss}",
Richard Hughes e9e839c
+                                 &dict);
Richard Hughes e9e839c
+  message_dict_add_strings(&dict, "Colorspace", colorspace);
Richard Hughes e9e839c
+  message_dict_add_strings(&dict, "Mode", COLORD_MODE_PHYSICAL);
Richard Hughes c444f44
+  if (ppd->manufacturer != NULL)
Richard Hughes c444f44
+    message_dict_add_strings(&dict, "Vendor", ppd->manufacturer);
Richard Hughes c444f44
+  if (ppd->modelname != NULL)
Richard Hughes c444f44
+    message_dict_add_strings(&dict, "Model", ppd->modelname);
Richard Hughes e9e839c
+  if (p->sanitized_device_uri != NULL)
Richard Hughes e9e839c
+    message_dict_add_strings(&dict, "Serial", p->sanitized_device_uri);
Richard Hughes e9e839c
+  message_dict_add_strings(&dict, "Kind", COLORD_KIND_PRINTER);
Richard Hughes e9e839c
+  dbus_message_iter_close_container(&args, &dict);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* send syncronous */
Richard Hughes e9e839c
+  dbus_error_init(&error);
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateDevice(%s,%s)",
Richard Hughes e9e839c
+                  device_id, scope);
Richard Hughes e9e839c
+  reply = dbus_connection_send_with_reply_and_block(con,
Richard Hughes e9e839c
+                                                    message,
Richard Hughes c444f44
+                                                    COLORD_DBUS_TIMEOUT,
Richard Hughes e9e839c
+                                                    &error);
Richard Hughes e9e839c
+  if (reply == NULL)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+        cupsdLogMessage(CUPSD_LOG_WARN,
Richard Hughes e9e839c
+                        "failed to CreateDevice: %s:%s",
Richard Hughes e9e839c
+                        error.name, error.message);
Richard Hughes e9e839c
+        dbus_error_free(&error);
Richard Hughes e9e839c
+        goto out;
Richard Hughes e9e839c
+  }
ba9bc8e
+
Richard Hughes e9e839c
+  /* get reply data */
Richard Hughes e9e839c
+  dbus_message_iter_init(reply, &args);
Richard Hughes e9e839c
+  if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+        cupsdLogMessage(CUPSD_LOG_WARN,
Richard Hughes e9e839c
+                        "incorrect reply type");
Richard Hughes e9e839c
+        goto out;
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  dbus_message_iter_get_basic(&args, &device_path);
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_DEBUG,
Richard Hughes e9e839c
+                  "created device %s",
Richard Hughes e9e839c
+                  device_path);
c45b42d
+
Richard Hughes e9e839c
+  /* add profiles */
Richard Hughes e9e839c
+  for (profile_path = cupsArrayFirst(profiles);
Richard Hughes e9e839c
+       profile_path;
Richard Hughes e9e839c
+       profile_path = cupsArrayNext(profiles))
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    colordDeviceAddProfile (device_path, profile_path, relation);
Richard Hughes e9e839c
+  }
c45b42d
+
ba9bc8e
+out:
ba9bc8e
+  free(default_profile_path);
Richard Hughes e9e839c
+  if (message != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(message);
Richard Hughes e9e839c
+  if (reply != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(reply);
ba9bc8e
+}
ba9bc8e
+
ba9bc8e
+/*
Richard Hughes e9e839c
+ * 'colordDeleteDevice()' - Delete a device
ba9bc8e
+ */
ba9bc8e
+
ba9bc8e
+static void
Richard Hughes e9e839c
+colordDeleteDevice (const char *device_id)      /* I - Device ID string */
ba9bc8e
+{
Richard Hughes e9e839c
+  DBusMessage           *message = NULL;        /* D-Bus request */
Richard Hughes e9e839c
+  DBusMessage           *reply = NULL;          /* D-Bus reply */
Richard Hughes e9e839c
+  DBusMessageIter       args;                   /* D-Bus method arguments */
Richard Hughes e9e839c
+  DBusError             error;                  /* D-Bus error */
ba9bc8e
+
ba9bc8e
+ /*
Richard Hughes e9e839c
+  * Create the device...
ba9bc8e
+  */
ba9bc8e
+
ba9bc8e
+  message = dbus_message_new_method_call("org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         "/org/freedesktop/ColorManager",
Richard Hughes e9e839c
+                                         "org.freedesktop.ColorManager",
Richard Hughes e9e839c
+                                         "DeleteDevice");
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  dbus_message_iter_init_append(message, &args);
Richard Hughes e9e839c
+  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* send syncronous */
Richard Hughes e9e839c
+  dbus_error_init(&error);
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling DeleteDevice(%s)", device_id);
Richard Hughes e9e839c
+  reply = dbus_connection_send_with_reply_and_block(con,
Richard Hughes e9e839c
+                                                    message,
Richard Hughes c444f44
+                                                    COLORD_DBUS_TIMEOUT,
Richard Hughes e9e839c
+                                                    &error);
Richard Hughes e9e839c
+  if (reply == NULL)
ba9bc8e
+  {
Richard Hughes c444f44
+        /* this can happen normally on start-up */
72d2aba
+        cupsdLogMessage(CUPSD_LOG_DEBUG,
72d2aba
+                        "failed to DeleteDevice: %s:%s",
Richard Hughes e9e839c
+                        error.name, error.message);
Richard Hughes e9e839c
+        dbus_error_free(&error);
Richard Hughes e9e839c
+        goto out;
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+out:
Richard Hughes e9e839c
+  if (message != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(message);
Richard Hughes e9e839c
+  if (reply != NULL)
Richard Hughes e9e839c
+    dbus_message_unref(reply);
Richard Hughes e9e839c
+}
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'colordGetQualifierFormat()' - Get the qualifier format.
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ * Notes: Returns a value of "ColorSpace.MediaType.Resolution" by default
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+char **
Richard Hughes e9e839c
+colordGetQualifierFormat(ppd_file_t *ppd)
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+  char                  **format;       /* Qualifier format tuple */
Richard Hughes e9e839c
+  const char            *tmp;           /* Temporary string */
Richard Hughes e9e839c
+  ppd_attr_t            *attr;          /* Profile attributes */
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* create 3-tuple */
Richard Hughes e9e839c
+  format = calloc(3, sizeof(char*));
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* get 1st section */
Richard Hughes e9e839c
+  tmp = "cupsICCQualifier1";
Richard Hughes e9e839c
+  attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  if (attr != NULL)
Richard Hughes e9e839c
+    tmp = attr->value;
Richard Hughes e9e839c
+  else
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "DefaultColorSpace";
Richard Hughes e9e839c
+    attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (attr == NULL)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "DefaultColorModel";
Richard Hughes e9e839c
+    attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (attr == NULL)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "";
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (strncmp(tmp, "Default", 7) == 0)
Richard Hughes e9e839c
+    tmp += 7;
Richard Hughes e9e839c
+  format[0] = strdup(tmp);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* get 2st section */
Richard Hughes e9e839c
+  tmp = "cupsICCQualifier2";
Richard Hughes e9e839c
+  attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  if (attr != NULL)
Richard Hughes e9e839c
+    tmp = attr->value;
Richard Hughes e9e839c
+  else
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "DefaultMediaType";
Richard Hughes e9e839c
+    attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (attr == NULL)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "";
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (strncmp(tmp, "Default", 7) == 0)
Richard Hughes e9e839c
+    tmp += 7;
Richard Hughes e9e839c
+  format[1] = strdup(tmp);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  /* get 3st section */
Richard Hughes e9e839c
+  tmp = "cupsICCQualifier3";
Richard Hughes e9e839c
+  attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  if (attr != NULL)
Richard Hughes e9e839c
+    tmp = attr->value;
Richard Hughes e9e839c
+  else
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "DefaultResolution";
Richard Hughes e9e839c
+    attr = ppdFindAttr(ppd, tmp, NULL);
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (attr == NULL)
Richard Hughes e9e839c
+  {
Richard Hughes e9e839c
+    tmp = "";
Richard Hughes e9e839c
+  }
Richard Hughes e9e839c
+  if (strncmp(tmp, "Default", 7) == 0)
Richard Hughes e9e839c
+    tmp += 7;
Richard Hughes e9e839c
+  format[2] = strdup(tmp);
ba9bc8e
+
Richard Hughes e9e839c
+  return format;
ba9bc8e
+}
ba9bc8e
+
ba9bc8e
+/*
Richard Hughes e9e839c
+ * 'colordRegisterPrinter()' - Register profiles for a printer.
ba9bc8e
+ */
ba9bc8e
+
ba9bc8e
+void
Richard Hughes e9e839c
+colordRegisterPrinter(cupsd_printer_t *p)    /* I - printer */
ba9bc8e
+{
Richard Hughes e9e839c
+  char                  ppdfile[1024],  /* PPD filename */
Richard Hughes e9e839c
+                        iccfile[1024];  /* ICC filename */
Richard Hughes e9e839c
+  ppd_file_t            *ppd;           /* PPD file */
Richard Hughes e9e839c
+  char                  *profile_path;  /* Profile path */
Richard Hughes e9e839c
+  cups_array_t          *profiles;      /* Profile paths array */
Richard Hughes e9e839c
+  const char            *profile_key;   /* Profile keyword */
Richard Hughes e9e839c
+  ppd_attr_t            *attr;          /* Profile attributes */
Richard Hughes e9e839c
+  const char            *device_colorspace;   /* Device colorspace */
Richard Hughes e9e839c
+  char                  **format;       /* Qualifier format tuple */
Richard Hughes e9e839c
+  int                   i;              /* Loop counter */
ba9bc8e
+
ba9bc8e
+ /*
2b082bd
+  * Do nothing for discovered printers as they will have local color
2b082bd
+  * correction
2b082bd
+  */
2b082bd
+
2b082bd
+  if (p->type & CUPS_PRINTER_DISCOVERED)
2b082bd
+    return;
2b082bd
+
2b082bd
+ /*
Richard Hughes e9e839c
+  * Ensure we have a DBus connection
ba9bc8e
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  colordStart();
ba9bc8e
+
ba9bc8e
+ /*
ba9bc8e
+  * Try opening the PPD file for this printer...
ba9bc8e
+  */
ba9bc8e
+
ba9bc8e
+  snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
ba9bc8e
+  if ((ppd = ppdOpenFile(ppdfile)) == NULL)
Richard Hughes e9e839c
+  {
2b082bd
+    cupsdLogMessage(CUPSD_LOG_DEBUG,
Richard Hughes e9e839c
+                    "cannot open %s",
Richard Hughes e9e839c
+                    ppdfile);
ba9bc8e
+    return;
Richard Hughes e9e839c
+  }
ba9bc8e
+
ba9bc8e
+ /*
Richard Hughes e9e839c
+  * Find out the qualifier format
ba9bc8e
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  format = colordGetQualifierFormat(ppd);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * See if we have any embedded profiles...
Richard Hughes e9e839c
+  */
Richard Hughes e9e839c
+
Richard Hughes c444f44
+  /* old CUPS has no cupsArrayNew3... */
Richard Hughes e9e839c
+  profiles = cupsArrayNew (NULL, NULL);
Richard Hughes c444f44
+  profile_key = "cupsICCProfile";
Richard Hughes e9e839c
+  attr = ppdFindAttr(ppd, profile_key, NULL);
Richard Hughes e9e839c
+  for (; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL))
ba9bc8e
+    if (attr->spec[0] && attr->value && attr->value[0])
ba9bc8e
+    {
ba9bc8e
+      if (attr->value[0] != '/')
Richard Hughes e9e839c
+        snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
Richard Hughes e9e839c
+                 attr->value);
ba9bc8e
+      else
Richard Hughes e9e839c
+        strlcpy(iccfile, attr->value, sizeof(iccfile));
ba9bc8e
+
ba9bc8e
+      if (access(iccfile, 0))
ba9bc8e
+      {
Richard Hughes e9e839c
+        cupsdLogMessage(CUPSD_LOG_WARN,
Richard Hughes e9e839c
+                        "no access to %s",
Richard Hughes e9e839c
+                        iccfile);
Richard Hughes e9e839c
+        continue;
ba9bc8e
+      }
ba9bc8e
+
Richard Hughes e9e839c
+      colordCreateProfile(profiles,
Richard Hughes e9e839c
+                          p->name,
Richard Hughes e9e839c
+                          attr->spec,
Richard Hughes 46d60c6
+                          COLORD_SPACE_UNKNOWN,
Richard Hughes e9e839c
+                          (const char **)format,
Richard Hughes e9e839c
+                          iccfile,
Richard Hughes e9e839c
+                          COLORD_SCOPE_TEMP);
ba9bc8e
+    }
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * Add the grayscale profile first.  We always have a grayscale profile.
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  colordCreateProfile(profiles,
Richard Hughes e9e839c
+                      p->name,
Richard Hughes e9e839c
+                      "Gray..",
Richard Hughes 46d60c6
+                      COLORD_SPACE_GRAY,
Richard Hughes e9e839c
+                      (const char **)format,
Richard Hughes e9e839c
+                      NULL,
Richard Hughes e9e839c
+                      COLORD_SCOPE_TEMP);
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * Then add the RGB/CMYK/DeviceN color profile...
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  device_colorspace = "unknown";
Richard Hughes e9e839c
+  switch (ppd->colorspace)
ba9bc8e
+  {
Richard Hughes e9e839c
+    case PPD_CS_RGB :
Richard Hughes e9e839c
+    case PPD_CS_CMY :
Richard Hughes e9e839c
+        device_colorspace = COLORD_SPACE_RGB;
Richard Hughes e9e839c
+        colordCreateProfile(profiles,
Richard Hughes e9e839c
+                            p->name,
Richard Hughes e9e839c
+                            "RGB..",
Richard Hughes 46d60c6
+                            COLORD_SPACE_RGB,
Richard Hughes e9e839c
+                            (const char **)format,
Richard Hughes e9e839c
+                            NULL,
Richard Hughes e9e839c
+                            COLORD_SCOPE_TEMP);
Richard Hughes e9e839c
+        break;
Richard Hughes e9e839c
+    case PPD_CS_RGBK :
Richard Hughes e9e839c
+    case PPD_CS_CMYK :
Richard Hughes e9e839c
+        device_colorspace = COLORD_SPACE_CMYK;
Richard Hughes e9e839c
+        colordCreateProfile(profiles,
Richard Hughes e9e839c
+                            p->name,
Richard Hughes e9e839c
+                            "CMYK..",
Richard Hughes 46d60c6
+                            COLORD_SPACE_CMYK,
Richard Hughes e9e839c
+                            (const char **)format,
Richard Hughes e9e839c
+                            NULL,
Richard Hughes e9e839c
+                            COLORD_SCOPE_TEMP);
Richard Hughes e9e839c
+        break;
Richard Hughes e9e839c
+    case PPD_CS_GRAY :
Richard Hughes c444f44
+        device_colorspace = COLORD_SPACE_GRAY;
Richard Hughes c444f44
+        break;
Richard Hughes e9e839c
+    case PPD_CS_N :
Richard Hughes e9e839c
+        colordCreateProfile(profiles,
Richard Hughes e9e839c
+                            p->name,
Richard Hughes e9e839c
+                            "DeviceN..",
Richard Hughes 46d60c6
+                            COLORD_SPACE_UNKNOWN,
Richard Hughes e9e839c
+                            (const char **)format,
Richard Hughes e9e839c
+                            NULL,
Richard Hughes e9e839c
+                            COLORD_SCOPE_TEMP);
Richard Hughes e9e839c
+        break;
Richard Hughes e9e839c
+  }
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * Register the device with colord.
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"",
Richard Hughes e9e839c
+                  p->name);
Richard Hughes e9e839c
+  colordCreateDevice (p,
Richard Hughes c444f44
+                      ppd,
Richard Hughes e9e839c
+                      profiles,
Richard Hughes e9e839c
+                      device_colorspace,
Richard Hughes e9e839c
+                      COLORD_RELATION_SOFT,
Richard Hughes e9e839c
+                      COLORD_SCOPE_TEMP);
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * Free any memory we used...
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  for (profile_path = cupsArrayFirst(profiles);
Richard Hughes e9e839c
+       profile_path != NULL;
Richard Hughes e9e839c
+       profile_path = cupsArrayNext(profiles)) {
Richard Hughes e9e839c
+    free(profile_path);
ba9bc8e
+  }
Richard Hughes e9e839c
+  cupsArrayDelete(profiles);
Richard Hughes e9e839c
+  for (i=0; i<3; i++)
Richard Hughes e9e839c
+    free(format[i]);
Richard Hughes e9e839c
+  free(format);
ba9bc8e
+
Richard Hughes e9e839c
+  ppdClose(ppd);
Richard Hughes e9e839c
+}
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'colordUnregisterPrinter()' - Unregister profiles for a printer.
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+void
Richard Hughes e9e839c
+colordUnregisterPrinter(cupsd_printer_t *p)  /* I - printer */
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+  char                  device_id[1024];        /* Device ID as understood by colord */
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * Ensure we have a DBus connection
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  colordStart();
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * Just delete the device itself, and leave the profiles registered
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
Richard Hughes e9e839c
+  colordDeleteDevice(device_id);
Richard Hughes e9e839c
+}
ba9bc8e
+
Richard Hughes e9e839c
+#endif /* HAVE_DBUS */
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * End of "$Id$".
Richard Hughes e9e839c
+ */
Richard Hughes e9e839c
--- /dev/null
Richard Hughes e9e839c
+++ b/scheduler/colord.h
Richard Hughes e9e839c
@@ -0,0 +1,22 @@
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * "$Id$"
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   colord integration for the CUPS scheduler.
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   Copyright 2011, Red Hat.
Richard Hughes e9e839c
+ *
Richard Hughes e9e839c
+ *   These coded instructions, statements, and computer programs are the
Richard Hughes e9e839c
+ *   property of Apple Inc. and are protected by Federal copyright
Richard Hughes e9e839c
+ *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
Richard Hughes e9e839c
+ *   which should have been included with this file.  If this file is
Richard Hughes e9e839c
+ *   file is missing or damaged, see the license at "http://www.cups.org/".
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+void	colordRegisterPrinter(cupsd_printer_t *p);
Richard Hughes e9e839c
+void	colordUnregisterPrinter(cupsd_printer_t *p);
Richard Hughes e9e839c
+void	colordStart(void);
Richard Hughes e9e839c
+void	colordStop(void);
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * End of "$Id$".
Richard Hughes e9e839c
+ */
Richard Hughes e9e839c
--- a/scheduler/ipp.c
Richard Hughes e9e839c
+++ b/scheduler/ipp.c
Richard Hughes e9e839c
@@ -2962,17 +2962,23 @@ add_printer(cupsd_client_t  *con,	/* I - Client connection */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
     cupsdSetPrinterReasons(printer, "none");
Richard Hughes e9e839c
 
Richard Hughes e9e839c
-#ifdef __APPLE__
Richard Hughes e9e839c
    /*
Richard Hughes e9e839c
     * (Re)register color profiles...
Richard Hughes e9e839c
     */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
     if (!RunUser)
Richard Hughes e9e839c
     {
Richard Hughes e9e839c
+      cupsdCmsRegisterPrinter(printer);
ba9bc8e
+#ifdef __APPLE__
ba9bc8e
+     /*
Richard Hughes e9e839c
+      * FIXME: ideally the ColorSync stuff would be moved to colorsync.c
Richard Hughes e9e839c
+      * and the colorsyncRegisterProfiles() would be called from
Richard Hughes e9e839c
+      * cupsdCmsRegisterPrinter() in printers.c
ba9bc8e
+      */
Richard Hughes e9e839c
       apple_unregister_profiles(printer);
Richard Hughes e9e839c
       apple_register_profiles(printer);
Richard Hughes e9e839c
-    }
Richard Hughes e9e839c
 #endif /* __APPLE__ */
ba9bc8e
+    }
Richard Hughes e9e839c
   }
Richard Hughes e9e839c
 
Richard Hughes e9e839c
  /*
Richard Hughes e9e839c
@@ -7052,11 +7058,17 @@ delete_printer(cupsd_client_t  *con,	/* I - Client connection */
Richard Hughes e9e839c
   snprintf(filename, sizeof(filename), "%s/%s.pwg3", CacheDir, printer->name);
Richard Hughes e9e839c
   unlink(filename);
Richard Hughes e9e839c
 
Richard Hughes e9e839c
-#ifdef __APPLE__
Richard Hughes e9e839c
  /*
Richard Hughes e9e839c
   * Unregister color profiles...
Richard Hughes e9e839c
   */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
+  cupsdCmsUnregisterPrinter(printer);
Richard Hughes e9e839c
+#ifdef __APPLE__
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
+  * FIXME: ideally the ColorSync stuff would be moved to colorsync.c
Richard Hughes e9e839c
+  * and the colorsyncUnregisterPrinter() would be called from
Richard Hughes e9e839c
+  * cupsdCmsUnregisterPrinter() in printers.c
Richard Hughes e9e839c
+  */
Richard Hughes e9e839c
   apple_unregister_profiles(printer);
Richard Hughes e9e839c
 #endif /* __APPLE__ */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
--- a/scheduler/printers.c
Richard Hughes e9e839c
+++ b/scheduler/printers.c
Richard Hughes e9e839c
@@ -80,6 +80,9 @@
Richard Hughes e9e839c
 #  include <sys/vfs.h>
Richard Hughes e9e839c
 #endif /* HAVE_SYS_VFS_H */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
+#ifdef HAVE_DBUS
Richard Hughes e9e839c
+# include "colord.h"
Richard Hughes e9e839c
+#endif /* HAVE_DBUS */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
 /*
Richard Hughes e9e839c
  * Local functions...
Richard Hughes e9e839c
@@ -740,6 +743,53 @@ cupsdDeleteAllPrinters(void)
Richard Hughes e9e839c
   }
Richard Hughes e9e839c
 }
Richard Hughes e9e839c
 
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'cupsdCmsRegisterPrinter()' - Registers a printer and profiles with the CMS
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+void
Richard Hughes e9e839c
+cupsdCmsRegisterPrinter(cupsd_printer_t *p)
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+#if defined(HAVE_DBUS)
Richard Hughes e9e839c
+  colordRegisterPrinter(p);
Richard Hughes e9e839c
+#endif /* defined(HAVE_DBUS) */
Richard Hughes e9e839c
+}
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'cupsdCmsUnregisterPrinter()' - Unregisters a printer and profiles with the CMS
Richard Hughes e9e839c
+ */
ba9bc8e
+
Richard Hughes e9e839c
+void
Richard Hughes e9e839c
+cupsdCmsUnregisterPrinter(cupsd_printer_t *p)
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+#if defined(HAVE_DBUS)
Richard Hughes e9e839c
+  colordUnregisterPrinter(p);
Richard Hughes e9e839c
+#endif /* defined(HAVE_DBUS) */
ba9bc8e
+}
ba9bc8e
+
Richard Hughes e9e839c
+/*
Richard Hughes e9e839c
+ * 'cupsdCmsStart()' - Starts the CMS
Richard Hughes e9e839c
+ */
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+void
Richard Hughes e9e839c
+cupsdCmsStart(void)
Richard Hughes e9e839c
+{
Richard Hughes e9e839c
+#if defined(HAVE_DBUS)
Richard Hughes e9e839c
+  colordStart();
Richard Hughes e9e839c
+#endif /* defined(HAVE_DBUS) */
Richard Hughes e9e839c
+}
ba9bc8e
+
ba9bc8e
+/*
Richard Hughes e9e839c
+ * 'cupsdCmsStop()' - Stops the CMS
ba9bc8e
+ */
ba9bc8e
+
ba9bc8e
+void
Richard Hughes e9e839c
+cupsdCmsStop(void)
ba9bc8e
+{
Richard Hughes e9e839c
+#if defined(HAVE_DBUS)
Richard Hughes e9e839c
+  colordStop();
Richard Hughes e9e839c
+#endif /* defined(HAVE_DBUS) */
Richard Hughes e9e839c
+}
Richard Hughes e9e839c
 
Richard Hughes e9e839c
 /*
Richard Hughes e9e839c
  * 'cupsdDeletePrinter()' - Delete a printer from the system.
Richard Hughes e9e839c
@@ -780,6 +830,12 @@ cupsdDeletePrinter(
Richard Hughes e9e839c
 		              "Job stopped.");
Richard Hughes e9e839c
 
Richard Hughes e9e839c
  /*
Richard Hughes e9e839c
+  * Unregister profiles...
Richard Hughes e9e839c
+  */
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+  cupsdCmsUnregisterPrinter(p);
Richard Hughes e9e839c
+
ba9bc8e
+ /*
Richard Hughes e9e839c
   * If this printer is the next for browsing, point to the next one...
Richard Hughes e9e839c
   */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
@@ -1488,6 +1544,12 @@ cupsdRenamePrinter(
Richard Hughes e9e839c
   p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name);
Richard Hughes e9e839c
 
Richard Hughes e9e839c
  /*
Richard Hughes e9e839c
+  * Unregister profiles...
ba9bc8e
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  cupsdCmsUnregisterPrinter(p);
ba9bc8e
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
   * Rename the printer...
Richard Hughes e9e839c
   */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
@@ -2700,6 +2762,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
Richard Hughes e9e839c
 #endif /* __sgi */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
  /*
Richard Hughes e9e839c
+  * Re-register profiles...
Richard Hughes e9e839c
+  */
ba9bc8e
+
Richard Hughes e9e839c
+  cupsdCmsUnregisterPrinter(p);
Richard Hughes e9e839c
+  cupsdCmsRegisterPrinter(p);
Richard Hughes e9e839c
+
Richard Hughes e9e839c
+ /*
Richard Hughes e9e839c
   * Let the browse protocols reflect the change
Richard Hughes e9e839c
   */
Richard Hughes e9e839c
 
Richard Hughes e9e839c
--- a/scheduler/printers.h
Richard Hughes e9e839c
+++ b/scheduler/printers.h
Richard Hughes e9e839c
@@ -175,6 +175,10 @@ extern const char	*cupsdValidateDest(const char *uri,
ba9bc8e
 			        	   cups_ptype_t *dtype,
ba9bc8e
 					   cupsd_printer_t **printer);
ba9bc8e
 extern void		cupsdWritePrintcap(void);
Richard Hughes e9e839c
+extern void		cupsdCmsRegisterPrinter(cupsd_printer_t *p);
Richard Hughes e9e839c
+extern void		cupsdCmsUnregisterPrinter(cupsd_printer_t *p);
Richard Hughes e9e839c
+extern void		cupsdCmsStart(void);
Richard Hughes e9e839c
+extern void		cupsdCmsStop(void);
ba9bc8e
 
ba9bc8e
 
ba9bc8e
 /*