From e9e839c4d380157d0e449fccd604fde6107bfa35 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Mar 07 2011 13:40:36 +0000 Subject: Updated colord patch. --- diff --git a/cups-icc.patch b/cups-icc.patch index 6c63e5b..0525ae5 100644 --- a/cups-icc.patch +++ b/cups-icc.patch @@ -1,1304 +1,521 @@ -diff -up cups-1.4.6/scheduler/ipp.c.icc cups-1.4.6/scheduler/ipp.c ---- cups-1.4.6/scheduler/ipp.c.icc 2011-01-12 16:16:39.865382541 +0000 -+++ cups-1.4.6/scheduler/ipp.c 2011-01-12 16:16:41.944280101 +0000 -@@ -32,10 +32,6 @@ - * based upon the printer state... - * add_queued_job_count() - Add the "queued-job-count" attribute for the - * specified printer or class. -- * apple_init_profile() - Initialize a color profile. -- * apple_register_profiles() - Register color profiles for a printer. -- * apple_unregister_profiles() - Remove color profiles for the specified -- * printer. - * apply_printer_defaults() - Apply printer default options to a job. - * authenticate_job() - Set job authentication info. - * cancel_all_jobs() - Cancel all print jobs. -@@ -107,11 +103,9 @@ - */ - - #include "cupsd.h" --#include - - #ifdef __APPLE__ - # include --# include - # ifdef HAVE_MEMBERSHIP_H - # include - # endif /* HAVE_MEMBERSHIP_H */ -@@ -142,14 +136,6 @@ static void add_printer(cupsd_client_t * - static void add_printer_state_reasons(cupsd_client_t *con, - cupsd_printer_t *p); - static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p); --#ifdef __APPLE__ --static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages, -- CMDeviceProfileInfo *profile, unsigned id, -- const char *name, const char *text, -- const char *iccfile); --static void apple_register_profiles(cupsd_printer_t *p); --static void apple_unregister_profiles(cupsd_printer_t *p); --#endif /* __APPLE__ */ - static void apply_printer_defaults(cupsd_printer_t *printer, - cupsd_job_t *job); - static void authenticate_job(cupsd_client_t *con, ipp_attribute_t *uri); -@@ -2947,17 +2933,15 @@ add_printer(cupsd_client_t *con, /* I - - - cupsdSetPrinterReasons(printer, "none"); - --#ifdef __APPLE__ - /* - * (Re)register color profiles... - */ - - if (!RunUser) - { -- apple_unregister_profiles(printer); -- apple_register_profiles(printer); -+ cupsdUnregisterColorProfiles(printer); -+ cupsdRegisterColorProfiles(printer); - } --#endif /* __APPLE__ */ - } - - /* -@@ -3093,553 +3077,6 @@ add_queued_job_count( - } - - --#ifdef __APPLE__ --/* -- * 'apple_init_profile()' - Initialize a color profile. -- */ -- --static void --apple_init_profile( -- ppd_file_t *ppd, /* I - PPD file */ -- cups_array_t *languages, /* I - Languages in the PPD file */ -- CMDeviceProfileInfo *profile, /* I - Profile record */ -- unsigned id, /* I - Profile ID */ -- const char *name, /* I - Profile name */ -- const char *text, /* I - Profile UI text */ -- const char *iccfile) /* I - ICC filename */ --{ -- char url[1024]; /* URL for profile filename */ -- CFMutableDictionaryRef dict; /* Dictionary for name */ -- char *language; /* Current language */ -- ppd_attr_t *attr; /* Profile attribute */ -- CFStringRef cflang, /* Language string */ -- cftext; /* Localized text */ -- -- -- /* -- * Build the profile name dictionary... -- */ -- -- dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, -- &kCFTypeDictionaryKeyCallBacks, -- &kCFTypeDictionaryValueCallBacks); -- -- cftext = CFStringCreateWithCString(kCFAllocatorDefault, text, -- kCFStringEncodingUTF8); -- -- if (cftext) -- { -- CFDictionarySetValue(dict, CFSTR("en"), cftext); -- CFRelease(cftext); -- } -- -- if (languages) -- { -- /* -- * Find localized names for the color profiles... -- */ -- -- cupsArraySave(ppd->sorted_attrs); -- -- for (language = (char *)cupsArrayFirst(languages); -- language; -- language = (char *)cupsArrayNext(languages)) -- { -- if (iccfile) -- { -- if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name, -- language)) == NULL) -- attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language); -- } -- else -- attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language); -- -- if (attr && attr->text[0]) -- { -- cflang = CFStringCreateWithCString(kCFAllocatorDefault, language, -- kCFStringEncodingUTF8); -- cftext = CFStringCreateWithCString(kCFAllocatorDefault, attr->text, -- kCFStringEncodingUTF8); -- -- if (cflang && cftext) -- CFDictionarySetValue(dict, cflang, cftext); -- -- if (cflang) -- CFRelease(cflang); -- -- if (cftext) -- CFRelease(cftext); -- } -- } -- -- cupsArrayRestore(ppd->sorted_attrs); -- } -- -- /* -- * Fill in the profile data... -- */ -- -- if (iccfile) -- httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "file", NULL, "", 0, -- iccfile); -- -- profile->dataVersion = cmDeviceProfileInfoVersion1; -- profile->profileID = id; -- profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase; -- profile->profileName = dict; -- -- if (iccfile) -- strlcpy(profile->profileLoc.u.pathLoc.path, iccfile, -- sizeof(profile->profileLoc.u.pathLoc.path)); --} -- -- --/* -- * 'apple_register_profiles()' - Register color profiles for a printer. -- */ -- --static void --apple_register_profiles( -- cupsd_printer_t *p) /* I - Printer */ --{ -- int i; /* Looping var */ -- char ppdfile[1024], /* PPD filename */ -- iccfile[1024], /* ICC filename */ -- selector[PPD_MAX_NAME]; -- /* Profile selection string */ -- ppd_file_t *ppd; /* PPD file */ -- ppd_attr_t *attr, /* Profile attributes */ -- *profileid_attr,/* cupsProfileID attribute */ -- *q1_attr, /* ColorModel (or other) qualifier */ -- *q2_attr, /* MediaType (or other) qualifier */ -- *q3_attr; /* Resolution (or other) qualifier */ -- char q_keyword[PPD_MAX_NAME]; -- /* Qualifier keyword */ -- const char *q1_choice, /* ColorModel (or other) choice */ -- *q2_choice, /* MediaType (or other) choice */ -- *q3_choice; /* Resolution (or other) choice */ -- const char *profile_key; /* Profile keyword */ -- ppd_option_t *cm_option; /* Color model option */ -- ppd_choice_t *cm_choice; /* Color model choice */ -- int num_profiles; /* Number of profiles */ -- CMError error; /* Last error */ -- unsigned device_id, /* Printer device ID */ -- profile_id, /* Profile ID */ -- default_profile_id = 0; -- /* Default profile ID */ -- CFMutableDictionaryRef device_name; /* Printer device name dictionary */ -- CFStringRef printer_name; /* Printer name string */ -- CMDeviceScope scope = /* Scope of the registration */ -- { -- kCFPreferencesAnyUser, -- kCFPreferencesCurrentHost -- }; -- CMDeviceProfileArrayPtr profiles; /* Profiles */ -- CMDeviceProfileInfo *profile; /* Current profile */ -- cups_array_t *languages; /* Languages array */ -- -- -- /* -- * Make sure ColorSync is available... -- */ -- -- if (CMRegisterColorDevice == NULL) -- return; -- -- /* -- * Try opening the PPD file for this printer... -- */ -- -- snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name); -- if ((ppd = ppdOpenFile(ppdfile)) == NULL) -- return; -- -- /* -- * See if we have any profiles... -- */ -- -- if ((attr = ppdFindAttr(ppd, "APTiogaProfile", NULL)) != NULL) -- profile_key = "APTiogaProfile"; -- else -- { -- attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); -- profile_key = "cupsICCProfile"; -- } -- -- for (num_profiles = 0; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL)) -- if (attr->spec[0] && attr->value && attr->value[0]) -- { -- if (attr->value[0] != '/') -- snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, -- attr->value); -- else -- strlcpy(iccfile, attr->value, sizeof(iccfile)); -- -- if (access(iccfile, 0)) -- continue; -- -- num_profiles ++; -- } -- -- -- /* -- * If we have profiles, add them... -- */ -- -- if (num_profiles > 0) -- { -- if (profile_key[0] == 'A') -- { -- /* -- * For Tioga PPDs, get the default profile using the DefaultAPTiogaProfile -- * attribute... -- */ -- -- if ((attr = ppdFindAttr(ppd, "DefaultAPTiogaProfile", NULL)) != NULL && -- attr->value) -- default_profile_id = atoi(attr->value); -- -- q1_choice = q2_choice = q3_choice = NULL; -- } -- else -- { -- /* -- * For CUPS PPDs, figure out the default profile selector values... -- */ -- -- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL && -- attr->value && attr->value[0]) -- { -- snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -- q1_attr = ppdFindAttr(ppd, q_keyword, NULL); -- } -- else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL) -- q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL); -- -- if (q1_attr && q1_attr->value && q1_attr->value[0]) -- q1_choice = q1_attr->value; -- else -- q1_choice = ""; -- -- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL && -- attr->value && attr->value[0]) -- { -- snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -- q2_attr = ppdFindAttr(ppd, q_keyword, NULL); -- } -- else -- q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL); -- -- if (q2_attr && q2_attr->value && q2_attr->value[0]) -- q2_choice = q2_attr->value; -- else -- q2_choice = NULL; -- -- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL && -- attr->value && attr->value[0]) -- { -- snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -- q3_attr = ppdFindAttr(ppd, q_keyword, NULL); -- } -- else -- q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL); -- -- if (q3_attr && q3_attr->value && q3_attr->value[0]) -- q3_choice = q3_attr->value; -- else -- q3_choice = NULL; -- } -- -- /* -- * Build the array of profiles... -- * -- * Note: This calloc actually requests slightly more memory than needed. -- */ -- -- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) -- { -- cupsdLogMessage(CUPSD_LOG_ERROR, -- "Unable to allocate memory for %d profiles!", -- num_profiles); -- ppdClose(ppd); -- return; -- } -- -- profiles->profileCount = num_profiles; -- languages = _ppdGetLanguages(ppd); -- -- for (profile = profiles->profiles, -- attr = ppdFindAttr(ppd, profile_key, NULL); -- attr; -- attr = ppdFindNextAttr(ppd, profile_key, NULL)) -- if (attr->spec[0] && attr->value && attr->value[0]) -- { -- /* -- * Add this profile... -- */ -- -- if (attr->value[0] != '/') -- snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, -- attr->value); -- else -- strlcpy(iccfile, attr->value, sizeof(iccfile)); -- -- if (access(iccfile, 0)) -- continue; -- -- if (profile_key[0] == 'c') -- { -- cupsArraySave(ppd->sorted_attrs); -- -- if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID", -- attr->spec)) != NULL && -- profileid_attr->value && isdigit(profileid_attr->value[0] & 255)) -- profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10); -- else -- profile_id = _ppdHashName(attr->spec); -- -- cupsArrayRestore(ppd->sorted_attrs); -- } -- else -- profile_id = atoi(attr->spec); -- -- apple_init_profile(ppd, languages, profile, profile_id, attr->spec, -- attr->text[0] ? attr->text : attr->spec, iccfile); -- -- profile ++; -- -- /* -- * See if this is the default profile... -- */ -- -- if (!default_profile_id) -- { -- if (q2_choice) -- { -- if (q3_choice) -- { -- snprintf(selector, sizeof(selector), "%s.%s.%s", -- q1_choice, q2_choice, q3_choice); -- if (!strcmp(selector, attr->spec)) -- default_profile_id = profile_id; -- } -- -- if (!default_profile_id) -- { -- snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, -- q2_choice); -- if (!strcmp(selector, attr->spec)) -- default_profile_id = profile_id; -- } -- } -- -- if (!default_profile_id && q3_choice) -- { -- snprintf(selector, sizeof(selector), "%s..%s", q1_choice, -- q3_choice); -- if (!strcmp(selector, attr->spec)) -- default_profile_id = profile_id; -- } -- -- if (!default_profile_id) -- { -- snprintf(selector, sizeof(selector), "%s..", q1_choice); -- if (!strcmp(selector, attr->spec)) -- default_profile_id = profile_id; -- } -- } -- } -- -- _ppdFreeLanguages(languages); -- } -- else if ((cm_option = ppdFindOption(ppd, "ColorModel")) != NULL) -- { -- /* -- * Extract profiles from ColorModel option... -- */ -- -- const char *profile_name; /* Name of generic profile */ -- -- -- num_profiles = cm_option->num_choices; -- -- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) -- { -- cupsdLogMessage(CUPSD_LOG_ERROR, -- "Unable to allocate memory for %d profiles!", -- num_profiles); -- ppdClose(ppd); -- return; -- } -- -- profiles->profileCount = num_profiles; -- -- for (profile = profiles->profiles, i = cm_option->num_choices, -- cm_choice = cm_option->choices; -- i > 0; -- i --, cm_choice ++, profile ++) -- { -- if (!strcmp(cm_choice->choice, "Gray") || -- !strcmp(cm_choice->choice, "Black")) -- profile_name = "Gray"; -- else if (!strcmp(cm_choice->choice, "RGB") || -- !strcmp(cm_choice->choice, "CMY")) -- profile_name = "RGB"; -- else if (!strcmp(cm_choice->choice, "CMYK") || -- !strcmp(cm_choice->choice, "KCMY")) -- profile_name = "CMYK"; -- else -- profile_name = "DeviceN"; -- -- snprintf(selector, sizeof(selector), "%s..", profile_name); -- profile_id = _ppdHashName(selector); -- -- apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice, -- cm_choice->text, NULL); -- -- if (cm_choice->marked) -- default_profile_id = profile_id; -- } -- } -- else -- { -- /* -- * Use the default colorspace... -- */ -- -- attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL); -- -- num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2; -- -- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) -- { -- cupsdLogMessage(CUPSD_LOG_ERROR, -- "Unable to allocate memory for %d profiles!", -- num_profiles); -- ppdClose(ppd); -- return; -- } -- -- profiles->profileCount = num_profiles; -- -- apple_init_profile(ppd, NULL, profiles->profiles, _ppdHashName("Gray.."), -- "Gray", "Gray", NULL); -- -- switch (ppd->colorspace) -- { -- case PPD_CS_RGB : -- case PPD_CS_CMY : -- apple_init_profile(ppd, NULL, profiles->profiles + 1, -- _ppdHashName("RGB.."), "RGB", "RGB", NULL); -- break; -- case PPD_CS_RGBK : -- case PPD_CS_CMYK : -- apple_init_profile(ppd, NULL, profiles->profiles + 1, -- _ppdHashName("CMYK.."), "CMYK", "CMYK", NULL); -- break; -- -- case PPD_CS_GRAY : -- if (attr) -- break; -- -- case PPD_CS_N : -- apple_init_profile(ppd, NULL, profiles->profiles + 1, -- _ppdHashName("DeviceN.."), "DeviceN", "DeviceN", -- NULL); -- break; -- } -- } -- -- if (num_profiles > 0) -- { -- /* -- * Make sure we have a default profile ID... -- */ -- -- if (!default_profile_id) -- default_profile_id = profiles->profiles[num_profiles - 1].profileID; -- -- /* -- * Get the device ID hash and pathelogical name dictionary. -- */ -- -- cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"", -- p->name); -- -- device_id = _ppdHashName(p->name); -- device_name = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, -- &kCFTypeDictionaryKeyCallBacks, -- &kCFTypeDictionaryValueCallBacks); -- printer_name = CFStringCreateWithCString(kCFAllocatorDefault, -- p->name, kCFStringEncodingUTF8); -- -- if (device_name && printer_name) -- { -- CFDictionarySetValue(device_name, CFSTR("en"), printer_name); -- -- /* -- * Register the device with ColorSync... -- */ -- -- error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id, -- device_name, &scope); -- -- /* -- * Register the profiles... -- */ -- -- if (error == noErr) -- error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id, -- default_profile_id, profiles); -- } -- else -- error = 1000; -- -- /* -- * Clean up... -- */ -- -- if (error != noErr) -- cupsdLogMessage(CUPSD_LOG_ERROR, -- "Unable to register ICC color profiles for \"%s\" - %d", -- p->name, (int)error); -- -- for (profile = profiles->profiles; -- num_profiles > 0; -- profile ++, num_profiles --) -- CFRelease(profile->profileName); -- -- free(profiles); -- -- if (printer_name) -- CFRelease(printer_name); -- -- if (device_name) -- CFRelease(device_name); -- } -- -- ppdClose(ppd); --} -- -- --/* -- * 'apple_unregister_profiles()' - Remove color profiles for the specified -- * printer. -- */ -- --static void --apple_unregister_profiles( -- cupsd_printer_t *p) /* I - Printer */ --{ -- /* -- * Make sure ColorSync is available... -- */ -- -- if (CMUnregisterColorDevice != NULL) -- CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name)); --} --#endif /* __APPLE__ */ -- - /* - * 'apply_printer_defaults()' - Apply printer default options to a job. - */ -@@ -6532,7 +5969,7 @@ delete_printer(cupsd_client_t *con, /* - * Unregister color profiles... - */ - -- apple_unregister_profiles(printer); -+ cupsdUnregisterColorProfiles(printer); - #endif /* __APPLE__ */ - - if (dtype & CUPS_PRINTER_CLASS) -diff -up cups-1.4.6/scheduler/printers.c.icc cups-1.4.6/scheduler/printers.c ---- cups-1.4.6/scheduler/printers.c.icc 2011-01-12 16:16:39.908380422 +0000 -+++ cups-1.4.6/scheduler/printers.c 2011-01-12 16:16:41.954279608 +0000 -@@ -5,6 +5,7 @@ - * - * Copyright 2007-2010 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. -+ * Copyright 2011 by Red Hat Inc. - * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright -@@ -40,6 +41,14 @@ - * cupsdValidateDest() - Validate a printer/class destination. - * cupsdWritePrintcap() - Write a pseudo-printcap file for older - * applications that need it... -+ * apple_init_profile() - Initialize a color profile. -+ * dbus_create_profile() - Initialise a color profile. -+ * dbus_create_device() - Initialise a color device. -+ * cupsdRegisterColorProfiles() -+ * - Register color profiles for a printer. -+ * cupsdUnregisterColorProfiles() -+ * - Remove color profiles for the specified -+ * printer. - * add_printer_defaults() - Add name-default attributes to the printer - * attributes. - * add_printer_filter() - Add a MIME filter for a printer. -@@ -64,10 +73,14 @@ - */ - - #include "cupsd.h" -+#include - #include - #ifdef HAVE_APPLICATIONSERVICES_H - # include - #endif /* HAVE_APPLICATIONSERVICES_H */ -+#ifdef __APPLE__ -+# include -+#endif /* __APPLE__ */ - #ifdef HAVE_SYS_MOUNT_H - # include - #endif /* HAVE_SYS_MOUNT_H */ -@@ -81,6 +94,16 @@ - # include - #endif /* HAVE_SYS_VFS_H */ - -+#ifdef HAVE_DBUS -+# include -+# ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND -+# define dbus_message_append_iter_init dbus_message_iter_init_append -+# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &(v)) -+# define dbus_message_iter_append_object_path(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_OBJECT_PATH, &(v)) -+# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &(v)) -+# endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */ -+#endif /* HAVE_DBUS */ +diff --git a/scheduler/Makefile b/scheduler/Makefile +index 0decf8f..a35ee82 100644 +--- a/scheduler/Makefile ++++ b/scheduler/Makefile +@@ -26,6 +26,7 @@ CUPSDOBJS = \ + env.o \ + main.o \ + ipp.o \ ++ colord.o \ + listen.o \ + job.o \ + log.o \ +diff --git a/scheduler/colord.c b/scheduler/colord.c +new file mode 100644 +index 0000000..2fdf401 +--- /dev/null ++++ b/scheduler/colord.c +@@ -0,0 +1,665 @@ ++/* ++ * "$Id$" ++ * ++ * colord integration for the CUPS scheduler. ++ * ++ * Copyright 2011, Red Hat. ++ * ++ * These coded instructions, statements, and computer programs are the ++ * property of Apple Inc. and are protected by Federal copyright ++ * law. Distribution and use rights are outlined in the file "LICENSE.txt" ++ * which should have been included with this file. If this file is ++ * file is missing or damaged, see the license at "http://www.cups.org/". ++ * ++ * Contents: ++ * ++ * colordRegisterPrinter() - Register profiles for a printer. ++ * colordUnregisterPrinter() - Unregister profiles for a printer. ++ * colordStart() - Get a connection to the system bus. ++ * colordStop() - Release any connection to the system bus ++ * so that added profiles and devices are ++ * automatically removed. ++ */ + - - /* - * Local functions... -@@ -102,7 +125,12 @@ static void write_irix_config(cupsd_prin - static void write_irix_state(cupsd_printer_t *p); - #endif /* __sgi */ - static void write_xml_string(cups_file_t *fp, const char *s); -- -+#ifdef __APPLE__ -+static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages, -+ CMDeviceProfileInfo *profile, unsigned id, -+ const char *name, const char *text, -+ const char *iccfile); -+#endif /* __APPLE__ */ - - /* - * 'cupsdAddPrinter()' - Add a printer to the system. -@@ -786,6 +814,14 @@ cupsdDeletePrinter( - update ? "Job stopped due to printer being deleted." : - "Job stopped."); - -+#ifdef HAVE_DBUS -+ /* -+ * Unregister the color profiles -+ */ ++/* ++ * Include necessary headers... ++ */ + -+ cupsdUnregisterColorProfiles(p); -+#endif /* HAVE_DBUS */ ++#include "cupsd.h" + - /* - * If this printer is the next for browsing, point to the next one... - */ -@@ -1533,6 +1569,14 @@ cupsdRenamePrinter( - mimeDeleteType(MimeDatabase, p->prefiltertype); - p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name); - +#ifdef HAVE_DBUS -+ /* -+ * Unregister the color profiles -+ */ -+ -+ cupsdUnregisterColorProfiles(p); -+#endif /* HAVE_DBUS */ + - /* - * Rename the printer... - */ -@@ -2722,6 +2766,14 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) - write_irix_state(p); - #endif /* __sgi */ - -+#ifdef HAVE_DBUS -+ /* -+ * (Re-)register the color profiles -+ */ -+ cupsdUnregisterColorProfiles(p); -+ cupsdRegisterColorProfiles(p); -+#endif /* HAVE_DBUS */ ++#include ++#include + - /* - * Let the browse protocols reflect the change - */ -@@ -5576,6 +5628,1031 @@ write_xml_string(cups_file_t *fp, /* I - - } - - -+#ifdef __APPLE__ +/* -+ * 'apple_init_profile()' - Initialize a color profile. ++ * Defines used by colord. See the reference docs for further details: ++ * http://colord.hughsie.com/api/ref-dbus.html + */ ++#define COLORD_SCOPE_NORMAL "normal" /* System scope */ ++#define COLORD_SCOPE_TEMP "temp" /* Process scope */ ++#define COLORD_SCOPE_DISK "disk" /* Lives forever, as stored in DB */ + -+static void -+apple_init_profile( -+ ppd_file_t *ppd, /* I - PPD file */ -+ cups_array_t *languages, /* I - Languages in the PPD file */ -+ CMDeviceProfileInfo *profile, /* I - Profile record */ -+ unsigned id, /* I - Profile ID */ -+ const char *name, /* I - Profile name */ -+ const char *text, /* I - Profile UI text */ -+ const char *iccfile) /* I - ICC filename */ -+{ -+ char url[1024]; /* URL for profile filename */ -+ CFMutableDictionaryRef dict; /* Dictionary for name */ -+ char *language; /* Current language */ -+ ppd_attr_t *attr; /* Profile attribute */ -+ CFStringRef cflang, /* Language string */ -+ cftext; /* Localized text */ -+ -+ -+ /* -+ * Build the profile name dictionary... -+ */ -+ -+ dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, -+ &kCFTypeDictionaryKeyCallBacks, -+ &kCFTypeDictionaryValueCallBacks); -+ -+ cftext = CFStringCreateWithCString(kCFAllocatorDefault, text, -+ kCFStringEncodingUTF8); -+ -+ if (cftext) -+ { -+ CFDictionarySetValue(dict, CFSTR("en"), cftext); -+ CFRelease(cftext); -+ } -+ -+ if (languages) -+ { -+ /* -+ * Find localized names for the color profiles... -+ */ -+ -+ cupsArraySave(ppd->sorted_attrs); ++#define COLORD_RELATION_SOFT "soft" /* Mapping is not default */ ++#define COLORD_RELATION_HARD "hard" /* Explicitly mapped profile */ + -+ for (language = (char *)cupsArrayFirst(languages); -+ language; -+ language = (char *)cupsArrayNext(languages)) -+ { -+ if (iccfile) -+ { -+ if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name, -+ language)) == NULL) -+ attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language); -+ } -+ else -+ attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language); -+ -+ if (attr && attr->text[0]) -+ { -+ cflang = CFStringCreateWithCString(kCFAllocatorDefault, language, -+ kCFStringEncodingUTF8); -+ cftext = CFStringCreateWithCString(kCFAllocatorDefault, attr->text, -+ kCFStringEncodingUTF8); -+ -+ if (cflang && cftext) -+ CFDictionarySetValue(dict, cflang, cftext); ++#define COLORD_SPACE_RGB "rgb" /* RGB colorspace */ ++#define COLORD_SPACE_CMYK "cmyk" /* CMYK colorspace */ + -+ if (cflang) -+ CFRelease(cflang); ++#define COLORD_MODE_PHYSICAL "physical" /* Actual device */ ++#define COLORD_MODE_VIRTUAL "virtual" /* Virtual device with no hardware */ + -+ if (cftext) -+ CFRelease(cftext); -+ } -+ } -+ -+ cupsArrayRestore(ppd->sorted_attrs); -+ } -+ -+ /* -+ * Fill in the profile data... -+ */ ++#define COLORD_KIND_PRINTER "printer" /* printing output device */ + -+ if (iccfile) -+ httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "file", NULL, "", 0, -+ iccfile); ++/* This is static */ ++static DBusConnection *con = NULL; + -+ profile->dataVersion = cmDeviceProfileInfoVersion1; -+ profile->profileID = id; -+ profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase; -+ profile->profileName = dict; ++/* ++ * 'colordStart()' - Get a connection to the system bus. ++ */ + -+ if (iccfile) -+ strlcpy(profile->profileLoc.u.pathLoc.path, iccfile, -+ sizeof(profile->profileLoc.u.pathLoc.path)); ++void ++colordStart(void) ++{ ++ if (con) ++ return; ++ con = dbus_bus_get (DBUS_BUS_SYSTEM, NULL); +} -+#endif /* __APPLE__ */ + -+ -+#if !defined(__APPLE__) && defined(HAVE_DBUS) +/* -+ * 'dbus_profile_profile_set_property()' - Set a property on a profile ++ * 'colordStop()' - Release any connection to the system bus so that ++ * added profiles and devices are automatically removed. + */ -+static void -+dbus_profile_profile_set_property (DBusConnection *con, /* I - D-Bus connection */ -+ const char *object_path, /* I - DBus path */ -+ const char *property_name, /* I - Property name */ -+ const char *property_value) /* I - Property value */ -+{ -+ DBusMessage *message; /* D-Bus message */ -+ DBusPendingCall *pending = NULL; /* D-Bus method call */ -+ DBusMessageIter args; /* D-Bus method arguments */ + -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ object_path, -+ "org.freedesktop.ColorManager.Profile", -+ "SetProperty"); -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_string(&args, property_name); -+ dbus_message_iter_append_string(&args, property_value); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling Profile %s SetProperty(%s=%s)", -+ object_path, property_name, property_value); -+ if (!dbus_connection_send_with_reply(con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_pending_call_block(pending); -+out: -+ dbus_pending_call_unref(pending); -+ dbus_message_unref(message); ++void ++colordStop(void) ++{ ++ if (con == NULL) ++ return; ++ dbus_connection_unref(con); ++ con = NULL; +} + +/* -+ * 'dbus_profile_device_set_property()' - Set a property on a device ++ * 'message_dict_add_strings()' - add two strings to a dictionary. + */ ++ +static void -+dbus_profile_device_set_property (DBusConnection *con, /* I - D-Bus connection */ -+ const char *object_path, /* I - DBus path */ -+ const char *property_name, /* I - Property name */ -+ const char *property_value) /* I - Property value */ ++message_dict_add_strings (DBusMessageIter *dict, ++ const char *key, ++ const char *value) +{ -+ DBusMessage *message; /* D-Bus message */ -+ DBusPendingCall *pending = NULL; /* D-Bus method call */ -+ DBusMessageIter args; /* D-Bus method arguments */ -+ -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ object_path, -+ "org.freedesktop.ColorManager.Device", -+ "SetProperty"); -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_string(&args, property_name); -+ dbus_message_iter_append_string(&args, property_value); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling Device %s SetProperty(%s=%s)", -+ object_path, property_name, property_value); -+ if (!dbus_connection_send_with_reply(con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_pending_call_block(pending); -+out: -+ dbus_pending_call_unref(pending); -+ dbus_message_unref(message); ++ DBusMessageIter entry; ++ dbus_message_iter_open_container(dict, ++ DBUS_TYPE_DICT_ENTRY, ++ NULL, ++ &entry); ++ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); ++ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &value); ++ dbus_message_iter_close_container(dict, &entry); +} + +/* -+ * 'dbus_create_profile()' - Create a color profile for a printer. ++ * 'colordCreateProfile()' - Create a color profile for a printer. ++ * ++ * Notes: When creating the device, we can create + */ ++ +static void -+dbus_create_profile (cups_array_t *profiles, /* I - Profiles array */ -+ DBusConnection *con, /* I - D-Bus connection */ -+ const char *printer_name, /* I - Printer name */ -+ const char *qualifier, /* I - Profile qualifier */ -+ const char *iccfile) /* I - ICC filename */ ++colordCreateProfile (cups_array_t *profiles, /* I - Profiles array */ ++ const char *printer_name, /* I - Printer name */ ++ const char *qualifier, /* I - Profile qualifier */ ++ const char **format, /* I - Profile qualifier format */ ++ const char *iccfile, /* I - ICC filename */ ++ const char *scope) /* I - The scope of the profile, e.g. ++ 'normal', 'temp' or 'disk' */ +{ -+ DBusMessage *message; /* D-Bus message */ -+ DBusMessageIter args; /* D-Bus method arguments */ -+ DBusPendingCall *pending; /* D-Bus method call */ -+ char *path = NULL; /* Profile path */ -+ char *idstr; /* Profile ID string */ -+ size_t idstrlen; /* Profile ID allocated length */ -+ int options = 1; /* Options for CreateProfile */ ++ DBusMessage *message = NULL; /* D-Bus request */ ++ DBusMessage *reply = NULL; /* D-Bus reply */ ++ DBusMessageIter args; /* D-Bus method arguments */ ++ DBusMessageIter dict; /* D-Bus method arguments */ ++ DBusError error; /* D-Bus error */ ++ int options = 1; /* Options for CreateDevice */ ++ char *idstr; /* Profile ID string */ ++ size_t idstrlen; /* Profile ID allocated length */ ++ const char *profile_path; /* Device object path */ ++ char format_str[1024]; /* Qualifier format as a string */ + + /* + * Create the profile... + */ + + message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ "/org/freedesktop/ColorManager", -+ "org.freedesktop.ColorManager", -+ "CreateProfile"); ++ "/org/freedesktop/ColorManager", ++ "org.freedesktop.ColorManager", ++ "CreateProfile"); + -+ dbus_message_append_iter_init(message, &args); ++ /* create a profile id */ + idstrlen = strlen (printer_name) + 1 + strlen (qualifier) + 1; + idstr = malloc (idstrlen); + if (!idstr) + goto out; -+ + snprintf (idstr, idstrlen, "%s-%s", printer_name, qualifier); -+ dbus_message_iter_append_string(&args, idstr); -+ dbus_message_iter_append_uint32(&args, options); ++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Using profile id of %s", ++ idstr); ++ ++ dbus_message_iter_init_append(message, &args); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &idstr); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope); ++ ++ /* mush the qualifier format into a simple string */ ++ snprintf(format_str, sizeof(format_str), "%s.%s.%s", ++ format[0], ++ format[1], ++ format[2]); ++ ++ /* set initial properties */ ++ dbus_message_iter_open_container(&args, ++ DBUS_TYPE_ARRAY, ++ "{ss}", ++ &dict); ++ message_dict_add_strings(&dict, "Qualifier", qualifier); ++ message_dict_add_strings(&dict, "Format", format_str); ++ if (iccfile != NULL) ++ message_dict_add_strings(&dict, "Filename", iccfile); ++ dbus_message_iter_close_container(&args, &dict); ++ ++ /* send syncronous */ ++ dbus_error_init(&error); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateProfile(%s,%d)", -+ idstr, options); -+ if (!dbus_connection_send_with_reply(con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_message_unref(message); -+ dbus_pending_call_block(pending); -+ message = dbus_pending_call_steal_reply(pending); -+// dbus_pending_call_unref(pending); <-fixme -+ -+ if (!message || -+ !dbus_message_iter_init(message, &args) || -+ dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) -+ goto out; -+ -+ dbus_message_iter_get_basic(&args, &path); -+ path = strdup(path); -+ cupsArrayAdd(profiles, strdup(path)); -+ dbus_message_unref(message); ++ idstr, options); ++ reply = dbus_connection_send_with_reply_and_block(con, ++ message, ++ -1, ++ &error); ++ if (reply == NULL) ++ { ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "failed to CreateProfile: %s:%s", ++ error.name, error.message); ++ dbus_error_free(&error); ++ goto out; ++ } + -+ /* -+ * Set the qualifier... -+ */ -+ dbus_profile_profile_set_property (con, path, "Qualifier", qualifier); ++ /* get reply data */ ++ dbus_message_iter_init(reply, &args); ++ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) ++ { ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "incorrect reply type"); ++ goto out; ++ } ++ dbus_message_iter_get_basic(&args, &profile_path); ++ cupsdLogMessage(CUPSD_LOG_DEBUG, ++ "created profile %s", ++ profile_path); ++ cupsArrayAdd(profiles, strdup(profile_path)); + -+ /* -+ * If we know the ICC file for it, set that now... -+ */ -+ if (iccfile) -+ dbus_profile_profile_set_property (con, path, "Filename", iccfile); +out: -+ free (path); ++ if (message != NULL) ++ dbus_message_unref(message); ++ if (reply != NULL) ++ dbus_message_unref(reply); + free (idstr); +} + -+ +/* -+ * 'dbus_create_device()' - Create a device and register profiles. ++ * 'colordDeviceAddProfile()' - Assign a profile to a device. + */ + +static void -+dbus_create_device (DBusConnection *con, /* I - D-Bus connection */ -+ cupsd_printer_t *p, /* I - Printer */ -+ cups_array_t *profiles, /* I - Profiles array */ -+ const char *default_profile_id) /* I - Default profile */ ++colordDeviceAddProfile (const char *device_path, /* I - Device object path */ ++ const char *profile_path, /* I - Profile object path */ ++ const char *relation) /* I - Device relation, either 'soft' or 'hard' */ +{ -+ DBusMessage *message; /* D-Bus message */ -+ DBusMessageIter args; /* D-Bus method arguments */ -+ DBusPendingCall *pending; /* D-Bus method call */ -+ const char *device_path_tmp; /* Device path data */ -+ char *device_path = NULL; /* Device path */ -+ const char *profile_path; /* Profile path */ -+ char *default_profile_path = NULL; -+ /* Default profile path */ -+ size_t default_path_len; -+ /* Length of profile path */ -+ int options = 1; /* Options for CreateDevice */ ++ DBusMessage *message = NULL; /* D-Bus request */ ++ DBusMessage *reply = NULL; /* D-Bus reply */ ++ DBusMessageIter args; /* D-Bus method arguments */ ++ DBusError error; /* D-Bus error */ + -+ /* -+ * Create the device... -+ */ + message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ "/org/freedesktop/ColorManager", -+ "org.freedesktop.ColorManager", -+ "CreateDevice"); -+ -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_string(&args, p->name); -+ dbus_message_iter_append_uint32(&args, options); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateDevice(%s,%d)", -+ p->name, options); -+ if (!dbus_connection_send_with_reply (con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_message_unref(message); -+ dbus_pending_call_block(pending); -+ message = dbus_pending_call_steal_reply(pending); -+ dbus_pending_call_unref(pending); -+ -+ if (!message || -+ !dbus_message_iter_init(message, &args) || -+ dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) -+ goto out; -+ -+ /* get device path, and duplicate so we can free the method */ -+ dbus_message_iter_get_basic(&args, &device_path_tmp); -+ device_path = strdup (device_path_tmp); -+ dbus_message_unref(message); -+ for (profile_path = cupsArrayFirst(profiles); -+ profile_path; -+ profile_path = cupsArrayNext(profiles)) ++ device_path, ++ "org.freedesktop.ColorManager.Device", ++ "AddProfile"); ++ ++ /* send profile path as the argument */ ++ dbus_message_iter_init_append(message, &args); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &relation); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &profile_path); ++ cupsdLogMessage(CUPSD_LOG_DEBUG, ++ "Calling %s:AddProfile(%s) [%s]", ++ device_path, profile_path, relation); ++ ++ /* send syncronous */ ++ dbus_error_init(&error); ++ reply = dbus_connection_send_with_reply_and_block(con, ++ message, ++ -1, ++ &error); ++ if (reply == NULL) + { -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ device_path, -+ "org.freedesktop.ColorManager.Device", -+ "AddProfile"); -+ -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_object_path(&args, profile_path); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling AddProfile(%s)", profile_path); -+ pending = NULL; -+ if (!dbus_connection_send_with_reply (con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_message_unref(message); -+ dbus_pending_call_block(pending); -+// message = dbus_pending_call_steal_reply(pending); -+ dbus_pending_call_unref(pending); ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "failed to AddProfile: %s:%s", ++ error.name, error.message); ++ dbus_error_free(&error); ++ goto out; + } ++out: ++ if (message != NULL) ++ dbus_message_unref(message); ++ if (reply != NULL) ++ dbus_message_unref(reply); ++} ++ ++/* ++ * 'colordCreateDevice()' - Create a device and register profiles. ++ */ ++ ++static void ++colordCreateDevice (cupsd_printer_t *p, /* I - Printer */ ++ cups_array_t *profiles, /* I - Profiles array */ ++ const char *colorspace, /* I - Device colorspace, e.g. 'rgb' */ ++ const char *relation, /* I - Profile relation, either 'soft' or 'hard' */ ++ const char *scope) /* I - The scope of the device, e.g. ++ 'normal', 'temp' or 'disk' */ ++{ ++ DBusMessage *message = NULL; /* D-Bus request */ ++ DBusMessage *reply = NULL; /* D-Bus reply */ ++ DBusMessageIter args; /* D-Bus method arguments */ ++ DBusMessageIter dict; /* D-Bus method arguments */ ++ DBusError error; /* D-Bus error */ ++ const char *device_path; /* Device object path */ ++ const char *profile_path; /* Profile path */ ++ char *default_profile_path = NULL; ++ /* Default profile path */ ++ char device_id[1024]; /* Device ID as understood by colord */ + + /* -+ * Set the default profile ++ * Create the device... + */ -+ default_path_len = strlen (p->name) + 1 + strlen (default_profile_id) + 1; -+ default_profile_path = malloc (default_path_len); -+ if (!default_profile_path) -+ goto out; -+ -+ snprintf(default_profile_path, default_path_len, "%s-%s", p->name, -+ default_profile_id); -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ device_path, -+ "org.freedesktop.ColorManager.Device", -+ "MakeProfileDefault"); + -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_string(&args, default_profile_path); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling MakeProfileDefault(%s)", -+ default_profile_path); -+ if (!dbus_connection_send_with_reply (con, message, &pending, -1)) -+ goto out; ++ snprintf(device_id, sizeof(device_id), "cups-%s", p->name); ++ device_path = device_id; + -+ dbus_connection_flush(con); -+ dbus_message_unref(message); -+ dbus_pending_call_block(pending); -+// message = dbus_pending_call_steal_reply(pending); -+ dbus_pending_call_unref(pending); ++ message = dbus_message_new_method_call("org.freedesktop.ColorManager", ++ "/org/freedesktop/ColorManager", ++ "org.freedesktop.ColorManager", ++ "CreateDevice"); ++ ++ dbus_message_iter_init_append(message, &args); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_path); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope); ++ ++ /* set initial properties */ ++ dbus_message_iter_open_container(&args, ++ DBUS_TYPE_ARRAY, ++ "{ss}", ++ &dict); ++ message_dict_add_strings(&dict, "Colorspace", colorspace); ++ message_dict_add_strings(&dict, "Mode", COLORD_MODE_PHYSICAL); ++ if (p->make_model != NULL) ++ message_dict_add_strings(&dict, "Vendor", p->make_model); ++ message_dict_add_strings(&dict, "Model", p->name); ++ if (p->sanitized_device_uri != NULL) ++ message_dict_add_strings(&dict, "Serial", p->sanitized_device_uri); ++ message_dict_add_strings(&dict, "Kind", COLORD_KIND_PRINTER); ++ dbus_message_iter_close_container(&args, &dict); ++ ++ /* send syncronous */ ++ dbus_error_init(&error); ++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateDevice(%s,%s)", ++ device_id, scope); ++ reply = dbus_connection_send_with_reply_and_block(con, ++ message, ++ -1, ++ &error); ++ if (reply == NULL) ++ { ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "failed to CreateDevice: %s:%s", ++ error.name, error.message); ++ dbus_error_free(&error); ++ goto out; ++ } + ++ /* get reply data */ ++ dbus_message_iter_init(reply, &args); ++ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) ++ { ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "incorrect reply type"); ++ goto out; ++ } ++ dbus_message_iter_get_basic(&args, &device_path); ++ cupsdLogMessage(CUPSD_LOG_DEBUG, ++ "created device %s", ++ device_path); + -+ /* -+ * Set other useful device attributes -+ */ -+ dbus_profile_device_set_property (con, device_path, "Kind", "printer"); -+ dbus_profile_device_set_property (con, device_path, "Model", p->make_model); ++ /* add profiles */ ++ for (profile_path = cupsArrayFirst(profiles); ++ profile_path; ++ profile_path = cupsArrayNext(profiles)) ++ { ++ colordDeviceAddProfile (device_path, profile_path, relation); ++ } + +out: + free(default_profile_path); -+ free(device_path); -+// dbus_message_unref(message); ++ if (message != NULL) ++ dbus_message_unref(message); ++ if (reply != NULL) ++ dbus_message_unref(reply); +} + -+ +/* -+ * 'dbus_delete_device_and_profiles()' - Delete previously registered -+ * color device and profiles ++ * 'colordDeleteDevice()' - Delete a device + */ + +static void -+dbus_delete_device_and_profiles(cupsd_printer_t *p) /* I - Printer */ ++colordDeleteDevice (const char *device_id) /* I - Device ID string */ +{ -+ DBusConnection *con; /* System D-Bus connection */ -+ DBusMessage *message; /* D-Bus message */ -+ DBusMessageIter args, array_args; /* D-Bus method arguments */ -+ DBusPendingCall *pending; /* D-Bus method call */ -+ const char *device_path; /* Device path */ -+ const char *options = ""; /* Options for GetProfilesForDevice */ -+ cups_array_t *profile_paths; /* Profile paths array */ -+ char *profile_path; /* Profile path */ -+ -+ con = dbus_bus_get (DBUS_BUS_SYSTEM, NULL); -+ if (!con) -+ return; ++ DBusMessage *message = NULL; /* D-Bus request */ ++ DBusMessage *reply = NULL; /* D-Bus reply */ ++ DBusMessageIter args; /* D-Bus method arguments */ ++ DBusError error; /* D-Bus error */ + + /* -+ * Get the device path -+ */ -+ -+ profile_paths = cupsArrayNew(NULL, NULL); -+ message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ "/org/freedesktop/ColorManager", -+ "org.freedesktop.ColorManager", -+ "FindDeviceById"); -+ -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_string(&args, p->name); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling FindDeviceById"); -+ if (!dbus_connection_send_with_reply(con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_message_unref(message); -+ dbus_pending_call_block(pending); -+ message = dbus_pending_call_steal_reply(pending); -+ dbus_pending_call_unref(pending); -+ -+ if (!message || -+ !dbus_message_iter_init(message, &args) || -+ dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) -+ goto out; -+ -+ dbus_message_iter_get_basic(&args, &device_path); -+ device_path = strdup(device_path); -+ -+ /* -+ * Get the profiles ++ * Create the device... + */ + -+ dbus_message_unref(message); + message = dbus_message_new_method_call("org.freedesktop.ColorManager", -+ "/org/freedesktop/ColorManager", -+ "org.freedesktop.ColorManager", -+ "GetProfilesForDevice"); -+ -+ dbus_message_append_iter_init(message, &args); -+ dbus_message_iter_append_object_path(&args, device_path); -+ dbus_message_iter_append_string(&args, options); -+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling GetProfilesForDevice(%s,\"\")", -+ device_path); -+ if (!dbus_connection_send_with_reply(con, message, &pending, -1)) -+ goto out; -+ -+ dbus_connection_flush(con); -+ dbus_message_unref(message); -+ dbus_pending_call_block(pending); -+ message = dbus_pending_call_steal_reply(pending); -+ dbus_pending_call_unref(pending); -+ -+ if (!message || -+ !dbus_message_iter_init(message, &args) || -+ dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) -+ goto out; -+ -+ dbus_message_iter_recurse(&args, &array_args); -+ do ++ "/org/freedesktop/ColorManager", ++ "org.freedesktop.ColorManager", ++ "DeleteDevice"); ++ ++ dbus_message_iter_init_append(message, &args); ++ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id); ++ ++ /* send syncronous */ ++ dbus_error_init(&error); ++ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling DeleteDevice(%s)", device_id); ++ reply = dbus_connection_send_with_reply_and_block(con, ++ message, ++ -1, ++ &error); ++ if (reply == NULL) + { -+ if (dbus_message_iter_get_arg_type(&array_args) == DBUS_TYPE_OBJECT_PATH) -+ { -+ dbus_message_iter_get_basic(&array_args, &profile_path); -+ cupsArrayAdd(profile_paths, strdup (profile_path)); -+ } -+ } while (dbus_message_iter_next(&array_args)); -+ -+ /* -+ * Delete each profile. -+ */ ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "failed to CreateDevice: %s:%s", ++ error.name, error.message); ++ dbus_error_free(&error); ++ goto out; ++ } ++out: ++ if (message != NULL) ++ dbus_message_unref(message); ++ if (reply != NULL) ++ dbus_message_unref(reply); ++} + ++/* ++ * 'colordGetQualifierFormat()' - Get the qualifier format. ++ * ++ * Notes: Returns a value of "ColorSpace.MediaType.Resolution" by default ++ */ + -+out: -+ for (profile_path = cupsArrayFirst(profile_paths); -+ profile_path; -+ profile_path = cupsArrayNext(profile_paths)) -+ free (profile_path); ++char ** ++colordGetQualifierFormat(ppd_file_t *ppd) ++{ ++ char **format; /* Qualifier format tuple */ ++ const char *tmp; /* Temporary string */ ++ ppd_attr_t *attr; /* Profile attributes */ ++ ++ /* create 3-tuple */ ++ format = calloc(3, sizeof(char*)); ++ ++ /* get 1st section */ ++ tmp = "cupsICCQualifier1"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ if (attr != NULL) ++ tmp = attr->value; ++ else ++ { ++ tmp = "DefaultColorSpace"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ } ++ if (attr == NULL) ++ { ++ tmp = "DefaultColorModel"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ } ++ if (attr == NULL) ++ { ++ tmp = ""; ++ } ++ if (strncmp(tmp, "Default", 7) == 0) ++ tmp += 7; ++ format[0] = strdup(tmp); ++ ++ /* get 2st section */ ++ tmp = "cupsICCQualifier2"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ if (attr != NULL) ++ tmp = attr->value; ++ else ++ { ++ tmp = "DefaultMediaType"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ } ++ if (attr == NULL) ++ { ++ tmp = ""; ++ } ++ if (strncmp(tmp, "Default", 7) == 0) ++ tmp += 7; ++ format[1] = strdup(tmp); ++ ++ /* get 3st section */ ++ tmp = "cupsICCQualifier3"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ if (attr != NULL) ++ tmp = attr->value; ++ else ++ { ++ tmp = "DefaultResolution"; ++ attr = ppdFindAttr(ppd, tmp, NULL); ++ } ++ if (attr == NULL) ++ { ++ tmp = ""; ++ } ++ if (strncmp(tmp, "Default", 7) == 0) ++ tmp += 7; ++ format[2] = strdup(tmp); + -+ cupsArrayDelete(profile_paths); -+ dbus_message_unref(message); -+ dbus_connection_unref(con); ++ return format; +} -+#endif /* !defined(__APPLE__) && defined(HAVE_DBUS) */ -+ + +/* -+ * 'cupsdRegisterColorProfiles()' - Register color profiles for a printer. ++ * 'colordRegisterPrinter()' - Register profiles for a printer. + */ + +void -+cupsdRegisterColorProfiles( -+ cupsd_printer_t *p) /* I - Printer */ ++colordRegisterPrinter(cupsd_printer_t *p) /* I - printer */ +{ -+ int i; /* Looping var */ -+ char ppdfile[1024], /* PPD filename */ -+ iccfile[1024], /* ICC filename */ -+ selector[PPD_MAX_NAME]; -+ /* Profile selection string */ -+ ppd_file_t *ppd; /* PPD file */ -+ ppd_attr_t *attr, /* Profile attributes */ -+ *q1_attr, /* ColorModel (or other) qualifier */ -+ *q2_attr, /* MediaType (or other) qualifier */ -+ *q3_attr; /* Resolution (or other) qualifier */ -+ char q_keyword[PPD_MAX_NAME]; -+ /* Qualifier keyword */ -+ const char *q1_choice, /* ColorModel (or other) choice */ -+ *q2_choice, /* MediaType (or other) choice */ -+ *q3_choice; /* Resolution (or other) choice */ -+ const char *profile_key; /* Profile keyword */ -+ ppd_option_t *cm_option; /* Color model option */ -+ ppd_choice_t *cm_choice; /* Color model choice */ -+ int num_profiles; /* Number of profiles */ -+#ifdef __APPLE__ -+ ppd_attr_t *profileid_attr;/* cupsProfileID attribute */ -+ unsigned profile_id, /* Profile ID */ -+ default_profile_id = 0; -+ /* Default profile ID */ -+ CMError error; /* Last error */ -+ CFMutableDictionaryRef device_name; /* Printer device name dictionary */ -+ unsigned device_id; /* Printer device ID */ -+ CFStringRef printer_name; /* Printer name string */ -+ CMDeviceScope scope = /* Scope of the registration */ -+ { -+ kCFPreferencesAnyUser, -+ kCFPreferencesCurrentHost -+ }; -+ CMDeviceProfileArrayPtr profiles; /* Profiles */ -+ CMDeviceProfileInfo *profile; /* Current profile */ -+ cups_array_t *languages; /* Languages array */ -+#elif HAVE_DBUS -+ const char *profile_id = NULL, -+ /* Profile ID */ -+ *default_profile_id = NULL; -+ /* Default profile ID */ -+ DBusError error; /* Error, if any */ -+ static DBusConnection *con; /* System D-Bus connection */ -+ cups_array_t *profiles; /* Profile paths array */ -+ char *profile_path; /* Profile path */ -+#endif /* HAVE_DBUS */ ++ char ppdfile[1024], /* PPD filename */ ++ iccfile[1024]; /* ICC filename */ ++ ppd_file_t *ppd; /* PPD file */ ++ char *profile_path; /* Profile path */ ++ cups_array_t *profiles; /* Profile paths array */ ++ const char *profile_key; /* Profile keyword */ ++ ppd_attr_t *attr; /* Profile attributes */ ++ const char *device_colorspace; /* Device colorspace */ ++ char **format; /* Qualifier format tuple */ ++ int i; /* Loop counter */ + -+ -+#ifdef __APPLE__ + /* -+ * Make sure ColorSync is available... ++ * Ensure we have a DBus connection + */ + -+ if (CMRegisterColorDevice == NULL) -+ return; -+#elif defined(HAVE_DBUS) -+ if (con && !dbus_connection_get_is_connected(con)) -+ { -+ dbus_connection_unref(con); -+ con = NULL; -+ } -+ -+ if (!con) -+ { -+ dbus_error_init(&error); -+ -+ con = dbus_bus_get (DBUS_BUS_SYSTEM, &error); -+ if (!con) -+ { -+ if (dbus_error_is_set(&error)) -+ cupsdLogMessage(CUPSD_LOG_DEBUG, -+ "D-Bus connection error: %s", error.message); -+ -+ dbus_error_free(&error); -+ return; -+ } -+ } -+ -+ profiles = cupsArrayNew (NULL, NULL); -+#else /* defined(__APPLE__) || defined(HAVE_DBUS) */ -+ return; -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ ++ colordStart(); + + /* + * Try opening the PPD file for this printer... @@ -1306,480 +523,361 @@ diff -up cups-1.4.6/scheduler/printers.c.icc cups-1.4.6/scheduler/printers.c + + snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name); + if ((ppd = ppdOpenFile(ppdfile)) == NULL) ++ { ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "cannot open %s", ++ ppdfile); + return; ++ } + + /* -+ * See if we have any profiles... ++ * Find out the qualifier format + */ + -+ if ((attr = ppdFindAttr(ppd, "APTiogaProfile", NULL)) != NULL) -+ profile_key = "APTiogaProfile"; -+ else ++ format = colordGetQualifierFormat(ppd); ++ ++ /* ++ * See if we have any embedded profiles... ++ */ ++ ++ profiles = cupsArrayNew (NULL, NULL); ++ profile_key = "APTiogaProfile"; ++ attr = ppdFindAttr(ppd, profile_key, NULL); ++ if (attr == NULL) + { -+ attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); + profile_key = "cupsICCProfile"; ++ attr = ppdFindAttr(ppd, profile_key, NULL); + } -+ -+ for (num_profiles = 0; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL)) ++ for (; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL)) + if (attr->spec[0] && attr->value && attr->value[0]) + { + if (attr->value[0] != '/') -+ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, -+ attr->value); ++ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, ++ attr->value); + else -+ strlcpy(iccfile, attr->value, sizeof(iccfile)); ++ strlcpy(iccfile, attr->value, sizeof(iccfile)); + + if (access(iccfile, 0)) -+ continue; -+ -+ num_profiles ++; -+ } -+ -+ -+ /* -+ * If we have profiles, add them... -+ */ -+ -+ if (num_profiles > 0) -+ { -+ if (profile_key[0] == 'A') -+ { -+ /* -+ * For Tioga PPDs, get the default profile using the DefaultAPTiogaProfile -+ * attribute... -+ */ -+ -+ if ((attr = ppdFindAttr(ppd, "DefaultAPTiogaProfile", NULL)) != NULL && -+ attr->value) + { -+#ifdef __APPLE__ -+ default_profile_id = atoi(attr->value); -+#elif HAVE_DBUS -+ default_profile_id = attr->value; -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ ++ cupsdLogMessage(CUPSD_LOG_WARN, ++ "no access to %s", ++ iccfile); ++ continue; + } + -+ q1_choice = q2_choice = q3_choice = NULL; ++ colordCreateProfile(profiles, ++ p->name, ++ attr->spec, ++ (const char **)format, ++ iccfile, ++ COLORD_SCOPE_TEMP); + } -+ else -+ { -+ /* -+ * For CUPS PPDs, figure out the default profile selector values... -+ */ -+ -+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -+ q1_attr = ppdFindAttr(ppd, q_keyword, NULL); -+ } -+ else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL) -+ q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL); -+ -+ if (q1_attr && q1_attr->value && q1_attr->value[0]) -+ q1_choice = q1_attr->value; -+ else -+ q1_choice = ""; -+ -+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -+ q2_attr = ppdFindAttr(ppd, q_keyword, NULL); -+ } -+ else -+ q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL); -+ -+ if (q2_attr && q2_attr->value && q2_attr->value[0]) -+ q2_choice = q2_attr->value; -+ else -+ q2_choice = NULL; -+ -+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL && -+ attr->value && attr->value[0]) -+ { -+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); -+ q3_attr = ppdFindAttr(ppd, q_keyword, NULL); -+ } -+ else -+ q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL); + -+ if (q3_attr && q3_attr->value && q3_attr->value[0]) -+ q3_choice = q3_attr->value; -+ else -+ q3_choice = NULL; -+ } -+ -+#ifdef __APPLE__ -+ /* -+ * Build the array of profiles... -+ * -+ * Note: This calloc actually requests slightly more memory than needed. -+ */ -+ -+ if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) -+ { -+ cupsdLogMessage(CUPSD_LOG_ERROR, -+ "Unable to allocate memory for %d profiles!", -+ num_profiles); -+ ppdClose(ppd); -+ return; -+ } -+ -+ profiles->profileCount = num_profiles; -+ languages = _ppdGetLanguages(ppd); -+ profile = profiles->profiles; -+#endif /* __APPLE__ */ -+ -+ for (attr = ppdFindAttr(ppd, profile_key, NULL); -+ attr; -+ attr = ppdFindNextAttr(ppd, profile_key, NULL)) -+ if (attr->spec[0] && attr->value && attr->value[0]) -+ { -+ /* -+ * Add this profile... -+ */ -+ -+ if (attr->value[0] != '/') -+ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, -+ attr->value); -+ else -+ strlcpy(iccfile, attr->value, sizeof(iccfile)); ++ /* ++ * Add the grayscale profile first. We always have a grayscale profile. ++ */ + -+ if (access(iccfile, 0)) -+ continue; ++ colordCreateProfile(profiles, ++ p->name, ++ "Gray..", ++ (const char **)format, ++ NULL, ++ COLORD_SCOPE_TEMP); + -+#ifdef __APPLE__ -+ if (profile_key[0] == 'c') -+ { -+ cupsArraySave(ppd->sorted_attrs); -+ -+ if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID", -+ attr->spec)) != NULL && -+ profileid_attr->value && isdigit(profileid_attr->value[0] & 255)) -+ profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10); -+ else -+ profile_id = _ppdHashName(attr->spec); -+ -+ cupsArrayRestore(ppd->sorted_attrs); -+ } -+ else -+ profile_id = atoi(attr->spec); -+ -+ apple_init_profile(ppd, languages, profile, profile_id, attr->spec, -+ attr->text[0] ? attr->text : attr->spec, iccfile); -+ profile ++; -+#elif defined(HAVE_DBUS) -+ profile_id = attr->spec; -+ dbus_create_profile(profiles, con, p->name, attr->spec, iccfile); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ -+ -+ /* -+ * See if this is the default profile... -+ */ -+ -+ if (!default_profile_id) -+ { -+ if (q2_choice) -+ { -+ if (q3_choice) -+ { -+ snprintf(selector, sizeof(selector), "%s.%s.%s", -+ q1_choice, q2_choice, q3_choice); -+ if (!strcmp(selector, attr->spec)) -+ default_profile_id = profile_id; -+ } -+ -+ if (!default_profile_id) -+ { -+ snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, -+ q2_choice); -+ if (!strcmp(selector, attr->spec)) -+ default_profile_id = profile_id; -+ } -+ } -+ -+ if (!default_profile_id && q3_choice) -+ { -+ snprintf(selector, sizeof(selector), "%s..%s", q1_choice, -+ q3_choice); -+ if (!strcmp(selector, attr->spec)) -+ default_profile_id = profile_id; -+ } -+ -+ if (!default_profile_id) -+ { -+ snprintf(selector, sizeof(selector), "%s..", q1_choice); -+ if (!strcmp(selector, attr->spec)) -+ default_profile_id = profile_id; -+ } -+ } -+ } ++ /* ++ * Then add the RGB/CMYK/DeviceN color profile... ++ */ + -+#ifdef __APPLE__ -+ _ppdFreeLanguages(languages); -+#endif /* __APPLE__ */ -+ } -+ else if ((cm_option = ppdFindOption(ppd, "ColorModel")) != NULL) ++ device_colorspace = "unknown"; ++ switch (ppd->colorspace) + { -+ /* -+ * Extract profiles from ColorModel option... -+ */ -+ -+ const char *profile_name; /* Name of generic profile */ -+ -+ -+ num_profiles = cm_option->num_choices; -+ -+#ifdef __APPLE__ -+ if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) -+ { -+ cupsdLogMessage(CUPSD_LOG_ERROR, -+ "Unable to allocate memory for %d profiles!", -+ num_profiles); -+ ppdClose(ppd); -+ return; -+ } ++ case PPD_CS_RGB : ++ case PPD_CS_CMY : ++ device_colorspace = COLORD_SPACE_RGB; ++ colordCreateProfile(profiles, ++ p->name, ++ "RGB..", ++ (const char **)format, ++ NULL, ++ COLORD_SCOPE_TEMP); ++ break; ++ case PPD_CS_RGBK : ++ case PPD_CS_CMYK : ++ device_colorspace = COLORD_SPACE_CMYK; ++ colordCreateProfile(profiles, ++ p->name, ++ "CMYK..", ++ (const char **)format, ++ NULL, ++ COLORD_SCOPE_TEMP); ++ break; ++ case PPD_CS_GRAY : ++ if (attr) ++ break; ++ case PPD_CS_N : ++ colordCreateProfile(profiles, ++ p->name, ++ "DeviceN..", ++ (const char **)format, ++ NULL, ++ COLORD_SCOPE_TEMP); ++ break; ++ } + -+ profiles->profileCount = num_profiles; -+ profile = profiles->profiles; -+#endif /* __APPLE__ */ ++ /* ++ * Register the device with colord. ++ */ + -+ for (i = cm_option->num_choices, cm_choice = cm_option->choices; -+ i > 0; -+ i --, cm_choice ++) -+ { -+ if (!strcmp(cm_choice->choice, "Gray") || -+ !strcmp(cm_choice->choice, "Black")) -+ profile_name = "Gray"; -+ else if (!strcmp(cm_choice->choice, "RGB") || -+ !strcmp(cm_choice->choice, "CMY")) -+ profile_name = "RGB"; -+ else if (!strcmp(cm_choice->choice, "CMYK") || -+ !strcmp(cm_choice->choice, "KCMY")) -+ profile_name = "CMYK"; -+ else -+ profile_name = "DeviceN"; ++ cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"", ++ p->name); ++ colordCreateDevice (p, ++ profiles, ++ device_colorspace, ++ COLORD_RELATION_SOFT, ++ COLORD_SCOPE_TEMP); + -+ snprintf(selector, sizeof(selector), "%s..", profile_name); ++ /* ++ * Free any memory we used... ++ */ + -+#ifdef __APPLE__ -+ profile_id = _ppdHashName(selector); -+ apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice, -+ cm_choice->text, NULL); -+ profile ++; -+#elif defined(HAVE_DBUS) -+ profile_id = selector; -+ dbus_create_profile(profiles, con, p->name, selector, NULL); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ -+ -+ if (cm_choice->marked) -+ default_profile_id = profile_id; -+ } ++ for (profile_path = cupsArrayFirst(profiles); ++ profile_path != NULL; ++ profile_path = cupsArrayNext(profiles)) { ++ free(profile_path); + } -+ else -+ { -+ /* -+ * Use the default colorspace... -+ */ -+ -+ attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL); -+ -+ num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2; -+ -+#ifdef __APPLE__ -+ if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) -+ { -+ cupsdLogMessage(CUPSD_LOG_ERROR, -+ "Unable to allocate memory for %d profiles!", -+ num_profiles); -+ ppdClose(ppd); -+ return; -+ } ++ cupsArrayDelete(profiles); ++ for (i=0; i<3; i++) ++ free(format[i]); ++ free(format); + -+ profiles->profileCount = num_profiles; ++ ppdClose(ppd); ++} + -+ apple_init_profile(ppd, NULL, profiles->profiles, _ppdHashName("Gray.."), -+ "Gray", "Gray", NULL); -+#elif defined(HAVE_DBUS) -+ profile_id = "Gray.."; -+ dbus_create_profile(profiles, con, p->name, profile_id, NULL); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ ++/* ++ * 'colordUnregisterPrinter()' - Unregister profiles for a printer. ++ */ + -+ switch (ppd->colorspace) -+ { -+ case PPD_CS_RGB : -+ case PPD_CS_CMY : -+#ifdef __APPLE__ -+ apple_init_profile(ppd, NULL, profiles->profiles + 1, -+ _ppdHashName("RGB.."), "RGB", "RGB", NULL); -+#elif defined(HAVE_DBUS) -+ profile_id = "RGB.."; -+ dbus_create_profile(profiles, con, p->name, profile_id, NULL); -+#endif /* HAVE_DBUS */ -+ break; -+ case PPD_CS_RGBK : -+ case PPD_CS_CMYK : -+#ifdef __APPLE__ -+ apple_init_profile(ppd, NULL, profiles->profiles + 1, -+ _ppdHashName("CMYK.."), "CMYK", "CMYK", NULL); -+#elif defined(HAVE_DBUS) -+ profile_id = "CMYK.."; -+ dbus_create_profile(profiles, con, p->name, profile_id, NULL); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ -+ break; ++void ++colordUnregisterPrinter(cupsd_printer_t *p) /* I - printer */ ++{ ++ char device_id[1024]; /* Device ID as understood by colord */ + -+ case PPD_CS_GRAY : -+ if (attr) -+ break; ++ /* ++ * Ensure we have a DBus connection ++ */ + -+ case PPD_CS_N : -+#ifdef __APPLE__ -+ apple_init_profile(ppd, NULL, profiles->profiles + 1, -+ _ppdHashName("DeviceN.."), "DeviceN", "DeviceN", -+ NULL); -+#elif defined(HAVE_DBUS) -+ profile_id = "DeviceN.."; -+ dbus_create_profile(profiles, con, p->name, profile_id, NULL); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ ++ colordStart(); + -+ break; -+ } -+ } ++ /* ++ * Just delete the device itself, and leave the profiles registered ++ */ + -+ if (num_profiles > 0) -+ { -+ /* -+ * Make sure we have a default profile ID... -+ */ ++ snprintf(device_id, sizeof(device_id), "cups-%s", p->name); ++ colordDeleteDevice(device_id); ++} + -+ if (!default_profile_id) -+ { -+#ifdef __APPLE__ -+ default_profile_id = profiles->profiles[num_profiles - 1].profileID; -+#elif HAVE_DBUS -+ default_profile_id = profile_id; -+#endif /* __APPLE__ */ -+ } ++#endif /* HAVE_DBUS */ + -+ /* -+ * Get the device ID hash and pathelogical name dictionary. -+ */ ++/* ++ * End of "$Id$". ++ */ +diff --git a/scheduler/colord.h b/scheduler/colord.h +new file mode 100644 +index 0000000..262b695 +--- /dev/null ++++ b/scheduler/colord.h +@@ -0,0 +1,22 @@ ++/* ++ * "$Id$" ++ * ++ * colord integration for the CUPS scheduler. ++ * ++ * Copyright 2011, Red Hat. ++ * ++ * These coded instructions, statements, and computer programs are the ++ * property of Apple Inc. and are protected by Federal copyright ++ * law. Distribution and use rights are outlined in the file "LICENSE.txt" ++ * which should have been included with this file. If this file is ++ * file is missing or damaged, see the license at "http://www.cups.org/". ++ */ + -+ cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"", -+ p->name); ++void colordRegisterPrinter(cupsd_printer_t *p); ++void colordUnregisterPrinter(cupsd_printer_t *p); ++void colordStart(void); ++void colordStop(void); + ++/* ++ * End of "$Id$". ++ */ +diff --git a/scheduler/ipp.c b/scheduler/ipp.c +index 6ba8339..55b7ed3 100644 +--- a/scheduler/ipp.c ++++ b/scheduler/ipp.c +@@ -2962,17 +2962,23 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ + + cupsdSetPrinterReasons(printer, "none"); + +-#ifdef __APPLE__ + /* + * (Re)register color profiles... + */ + + if (!RunUser) + { ++ cupsdCmsRegisterPrinter(printer); +#ifdef __APPLE__ -+ device_id = _ppdHashName(p->name); -+ -+ device_name = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, -+ &kCFTypeDictionaryKeyCallBacks, -+ &kCFTypeDictionaryValueCallBacks); -+ printer_name = CFStringCreateWithCString(kCFAllocatorDefault, -+ p->name, kCFStringEncodingUTF8); -+ -+ if (device_name && printer_name) -+ { -+ CFDictionarySetValue(device_name, CFSTR("en"), printer_name); -+ + /* -+ * Register the device with ColorSync... ++ * FIXME: ideally the ColorSync stuff would be moved to colorsync.c ++ * and the colorsyncRegisterProfiles() would be called from ++ * cupsdCmsRegisterPrinter() in printers.c + */ -+ -+ error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id, -+ device_name, &scope); -+ -+ /* -+ * Register the profiles... -+ */ -+ -+ if (error == noErr) -+ error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id, -+ default_profile_id, profiles); + apple_unregister_profiles(printer); + apple_register_profiles(printer); +- } + #endif /* __APPLE__ */ + } -+ else -+ error = 1000; -+#elif defined(HAVE_DBUS) -+ dbus_create_device (con, p, profiles, default_profile_id); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ + } + + /* +@@ -7052,11 +7058,17 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ + snprintf(filename, sizeof(filename), "%s/%s.pwg3", CacheDir, printer->name); + unlink(filename); + +-#ifdef __APPLE__ + /* + * Unregister color profiles... + */ + ++ cupsdCmsUnregisterPrinter(printer); ++#ifdef __APPLE__ ++ /* ++ * FIXME: ideally the ColorSync stuff would be moved to colorsync.c ++ * and the colorsyncUnregisterPrinter() would be called from ++ * cupsdCmsUnregisterPrinter() in printers.c ++ */ + apple_unregister_profiles(printer); + #endif /* __APPLE__ */ + +diff --git a/scheduler/printers.c b/scheduler/printers.c +index aedae5d..0947aeb 100644 +--- a/scheduler/printers.c ++++ b/scheduler/printers.c +@@ -80,6 +80,9 @@ + # include + #endif /* HAVE_SYS_VFS_H */ + ++#ifdef HAVE_DBUS ++# include "colord.h" ++#endif /* HAVE_DBUS */ + + /* + * Local functions... +@@ -740,6 +743,53 @@ cupsdDeleteAllPrinters(void) + } + } + ++/* ++ * 'cupsdCmsRegisterPrinter()' - Registers a printer and profiles with the CMS ++ */ + -+ /* -+ * Clean up... -+ */ ++void ++cupsdCmsRegisterPrinter(cupsd_printer_t *p) ++{ ++#if defined(HAVE_DBUS) ++ colordRegisterPrinter(p); ++#endif /* defined(HAVE_DBUS) */ ++} + -+#ifdef __APPLE__ -+ if (error != noErr) -+ cupsdLogMessage(CUPSD_LOG_ERROR, -+ "Unable to register ICC color profiles for \"%s\" - %d", -+ p->name, (int)error); -+ -+ for (profile = profiles->profiles; -+ num_profiles > 0; -+ profile ++, num_profiles --) -+ CFRelease(profile->profileName); -+ -+ free(profiles); -+ -+ if (printer_name) -+ CFRelease(printer_name); -+ -+ if (device_name) -+ CFRelease(device_name); -+#elif defined(HAVE_DBUS) -+ for (profile_path = cupsArrayFirst(profiles); -+ profile_path; -+ profile_path = cupsArrayNext(profiles)) -+ free (profile_path); -+ -+ cupsArrayDelete(profiles); -+ dbus_connection_flush(con); -+ -+ /* -+ * Don't unref the connection but instead keep it around for future -+ * calls (it is a local static variable). Once we disconnect from -+ * the bus all our devices and profiles will be gone. -+ */ -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ -+ } ++/* ++ * 'cupsdCmsUnregisterPrinter()' - Unregisters a printer and profiles with the CMS ++ */ + -+ ppdClose(ppd); ++void ++cupsdCmsUnregisterPrinter(cupsd_printer_t *p) ++{ ++#if defined(HAVE_DBUS) ++ colordUnregisterPrinter(p); ++#endif /* defined(HAVE_DBUS) */ +} + ++/* ++ * 'cupsdCmsStart()' - Starts the CMS ++ */ ++ ++void ++cupsdCmsStart(void) ++{ ++#if defined(HAVE_DBUS) ++ colordStart(); ++#endif /* defined(HAVE_DBUS) */ ++} + +/* -+ * 'cupsdUnregisterColorProfiles()' - Remove color profiles for the specified -+ * printer. ++ * 'cupsdCmsStop()' - Stops the CMS + */ + +void -+cupsdUnregisterColorProfiles( -+ cupsd_printer_t *p) /* I - Printer */ ++cupsdCmsStop(void) +{ -+#ifdef __APPLE__ ++#if defined(HAVE_DBUS) ++ colordStop(); ++#endif /* defined(HAVE_DBUS) */ ++} + + /* + * 'cupsdDeletePrinter()' - Delete a printer from the system. +@@ -780,6 +830,12 @@ cupsdDeletePrinter( + "Job stopped."); + + /* ++ * Unregister profiles... ++ */ ++ ++ cupsdCmsUnregisterPrinter(p); ++ + /* -+ * Make sure ColorSync is available... + * If this printer is the next for browsing, point to the next one... + */ + +@@ -1488,6 +1544,12 @@ cupsdRenamePrinter( + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name); + + /* ++ * Unregister profiles... + */ + -+ if (CMUnregisterColorDevice != NULL) -+ CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name)); -+#elif defined(HAVE_DBUS) -+ dbus_delete_device_and_profiles (p); -+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */ -+} ++ cupsdCmsUnregisterPrinter(p); + ++ /* + * Rename the printer... + */ + +@@ -2700,6 +2762,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ + #endif /* __sgi */ + + /* ++ * Re-register profiles... ++ */ + - /* - * End of "$Id: printers.c 9313 2010-09-22 18:35:07Z mike $". - */ -diff -up cups-1.4.6/scheduler/printers.h.icc cups-1.4.6/scheduler/printers.h ---- cups-1.4.6/scheduler/printers.h.icc 2011-01-12 16:16:39.911380276 +0000 -+++ cups-1.4.6/scheduler/printers.h 2011-01-12 16:16:41.956279504 +0000 -@@ -189,6 +189,8 @@ extern const char *cupsdValidateDest(con ++ cupsdCmsUnregisterPrinter(p); ++ cupsdCmsRegisterPrinter(p); ++ ++ /* + * Let the browse protocols reflect the change + */ + +diff --git a/scheduler/printers.h b/scheduler/printers.h +index 3afc88d..85d2c88 100644 +--- a/scheduler/printers.h ++++ b/scheduler/printers.h +@@ -175,6 +175,10 @@ extern const char *cupsdValidateDest(const char *uri, cups_ptype_t *dtype, cupsd_printer_t **printer); extern void cupsdWritePrintcap(void); -+extern void cupsdRegisterColorProfiles(cupsd_printer_t *printer); -+extern void cupsdUnregisterColorProfiles(cupsd_printer_t *printer); ++extern void cupsdCmsRegisterPrinter(cupsd_printer_t *p); ++extern void cupsdCmsUnregisterPrinter(cupsd_printer_t *p); ++extern void cupsdCmsStart(void); ++extern void cupsdCmsStop(void); /* diff --git a/cups-lspp.patch b/cups-lspp.patch index a6122ea..6301e6a 100644 --- a/cups-lspp.patch +++ b/cups-lspp.patch @@ -1,6 +1,6 @@ -diff -up cups-1.4.6/config.h.in.lspp cups-1.4.6/config.h.in ---- cups-1.4.6/config.h.in.lspp 2011-01-14 17:14:06.357403733 +0000 -+++ cups-1.4.6/config.h.in 2011-01-14 17:14:06.416404437 +0000 +diff -urNp cups-1.4.6.old/config.h.in cups-1.4.6/config.h.in +--- cups-1.4.6.old/config.h.in 2011-03-07 13:34:52.585876279 +0000 ++++ cups-1.4.6/config.h.in 2011-03-07 13:35:07.138875913 +0000 @@ -672,6 +672,12 @@ #undef HAVE_SYS_STATVFS_H #undef HAVE_SYS_VFS_H @@ -14,9 +14,9 @@ diff -up cups-1.4.6/config.h.in.lspp cups-1.4.6/config.h.in #endif /* !_CUPS_CONFIG_H_ */ -diff -up cups-1.4.6/config-scripts/cups-lspp.m4.lspp cups-1.4.6/config-scripts/cups-lspp.m4 ---- cups-1.4.6/config-scripts/cups-lspp.m4.lspp 2011-01-14 17:14:06.417404449 +0000 -+++ cups-1.4.6/config-scripts/cups-lspp.m4 2011-01-14 17:14:06.417404449 +0000 +diff -urNp cups-1.4.6.old/config-scripts/cups-lspp.m4 cups-1.4.6/config-scripts/cups-lspp.m4 +--- cups-1.4.6.old/config-scripts/cups-lspp.m4 1970-01-01 01:00:00.000000000 +0100 ++++ cups-1.4.6/config-scripts/cups-lspp.m4 2011-03-07 13:35:07.139875938 +0000 @@ -0,0 +1,36 @@ +dnl +dnl LSPP code for the Common UNIX Printing System (CUPS). @@ -54,9 +54,9 @@ diff -up cups-1.4.6/config-scripts/cups-lspp.m4.lspp cups-1.4.6/config-scripts/c + ;; + esac +fi -diff -up cups-1.4.6/configure.in.lspp cups-1.4.6/configure.in ---- cups-1.4.6/configure.in.lspp 2010-06-22 22:42:44.000000000 +0100 -+++ cups-1.4.6/configure.in 2011-01-14 17:14:06.418404460 +0000 +diff -urNp cups-1.4.6.old/configure.in cups-1.4.6/configure.in +--- cups-1.4.6.old/configure.in 2011-03-07 13:34:52.521876279 +0000 ++++ cups-1.4.6/configure.in 2011-03-07 13:35:07.139875938 +0000 @@ -42,6 +42,8 @@ sinclude(config-scripts/cups-pap.m4) sinclude(config-scripts/cups-pdf.m4) sinclude(config-scripts/cups-scripting.m4) @@ -66,9 +66,9 @@ diff -up cups-1.4.6/configure.in.lspp cups-1.4.6/configure.in INSTALL_LANGUAGES="" UNINSTALL_LANGUAGES="" LANGFILES="" -diff -up cups-1.4.6/cups/cups.h.lspp cups-1.4.6/cups/cups.h ---- cups-1.4.6/cups/cups.h.lspp 2010-11-17 19:59:14.000000000 +0000 -+++ cups-1.4.6/cups/cups.h 2011-01-14 17:14:06.419404472 +0000 +diff -urNp cups-1.4.6.old/cups/cups.h cups-1.4.6/cups/cups.h +--- cups-1.4.6.old/cups/cups.h 2011-03-07 13:34:53.042876279 +0000 ++++ cups-1.4.6/cups/cups.h 2011-03-07 13:35:07.140875960 +0000 @@ -15,6 +15,9 @@ * This file is subject to the Apple OS-Developed Software exception. */ @@ -92,9 +92,9 @@ diff -up cups-1.4.6/cups/cups.h.lspp cups-1.4.6/cups/cups.h /* * Types and structures... */ -diff -up cups-1.4.6/data/Makefile.lspp cups-1.4.6/data/Makefile ---- cups-1.4.6/data/Makefile.lspp 2008-11-12 19:30:57.000000000 +0000 -+++ cups-1.4.6/data/Makefile 2011-01-14 17:14:06.420404484 +0000 +diff -urNp cups-1.4.6.old/data/Makefile cups-1.4.6/data/Makefile +--- cups-1.4.6.old/data/Makefile 2011-03-07 13:34:52.596876279 +0000 ++++ cups-1.4.6/data/Makefile 2011-03-07 13:35:07.140875960 +0000 @@ -25,7 +25,10 @@ BANNERS = \ secret \ standard \ @@ -107,9 +107,9 @@ diff -up cups-1.4.6/data/Makefile.lspp cups-1.4.6/data/Makefile CHARMAPS = \ euc-cn.txt \ -diff -up cups-1.4.6/data/mls.lspp cups-1.4.6/data/mls ---- cups-1.4.6/data/mls.lspp 2011-01-14 17:14:06.420404484 +0000 -+++ cups-1.4.6/data/mls 2011-01-14 17:14:06.421404496 +0000 +diff -urNp cups-1.4.6.old/data/mls cups-1.4.6/data/mls +--- cups-1.4.6.old/data/mls 1970-01-01 01:00:00.000000000 +0100 ++++ cups-1.4.6/data/mls 2011-03-07 13:35:07.141875981 +0000 @@ -0,0 +1,261 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 @@ -372,9 +372,9 @@ diff -up cups-1.4.6/data/mls.lspp cups-1.4.6/data/mls +% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $". +% +%%EOF -diff -up cups-1.4.6/data/selinux.lspp cups-1.4.6/data/selinux ---- cups-1.4.6/data/selinux.lspp 2011-01-14 17:14:06.422404508 +0000 -+++ cups-1.4.6/data/selinux 2011-01-14 17:14:06.422404508 +0000 +diff -urNp cups-1.4.6.old/data/selinux cups-1.4.6/data/selinux +--- cups-1.4.6.old/data/selinux 1970-01-01 01:00:00.000000000 +0100 ++++ cups-1.4.6/data/selinux 2011-03-07 13:35:07.141875981 +0000 @@ -0,0 +1,261 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 @@ -637,9 +637,9 @@ diff -up cups-1.4.6/data/selinux.lspp cups-1.4.6/data/selinux +% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $". +% +%%EOF -diff -up cups-1.4.6/data/te.lspp cups-1.4.6/data/te ---- cups-1.4.6/data/te.lspp 2011-01-14 17:14:06.423404520 +0000 -+++ cups-1.4.6/data/te 2011-01-14 17:14:06.423404520 +0000 +diff -urNp cups-1.4.6.old/data/te cups-1.4.6/data/te +--- cups-1.4.6.old/data/te 1970-01-01 01:00:00.000000000 +0100 ++++ cups-1.4.6/data/te 2011-03-07 13:35:07.142875996 +0000 @@ -0,0 +1,261 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 @@ -902,9 +902,9 @@ diff -up cups-1.4.6/data/te.lspp cups-1.4.6/data/te +% End of "$Id: mls_template,v 1.1 2005/06/27 18:44:46 colmo Exp $". +% +%%EOF -diff -up cups-1.4.6/filter/common.c.lspp cups-1.4.6/filter/common.c ---- cups-1.4.6/filter/common.c.lspp 2007-07-11 22:46:42.000000000 +0100 -+++ cups-1.4.6/filter/common.c 2011-01-14 17:14:06.424404532 +0000 +diff -urNp cups-1.4.6.old/filter/common.c cups-1.4.6/filter/common.c +--- cups-1.4.6.old/filter/common.c 2011-03-07 13:34:53.361876279 +0000 ++++ cups-1.4.6/filter/common.c 2011-03-07 13:35:07.143876025 +0000 @@ -30,6 +30,12 @@ * Include necessary headers... */ @@ -1073,9 +1073,9 @@ diff -up cups-1.4.6/filter/common.c.lspp cups-1.4.6/filter/common.c /* -diff -up cups-1.4.6/filter/pstops.c.lspp cups-1.4.6/filter/pstops.c ---- cups-1.4.6/filter/pstops.c.lspp 2011-01-14 17:14:06.204401909 +0000 -+++ cups-1.4.6/filter/pstops.c 2011-01-14 17:14:06.429404592 +0000 +diff -urNp cups-1.4.6.old/filter/pstops.c cups-1.4.6/filter/pstops.c +--- cups-1.4.6.old/filter/pstops.c 2011-03-07 13:34:53.372876279 +0000 ++++ cups-1.4.6/filter/pstops.c 2011-03-07 13:35:07.144876057 +0000 @@ -3326,6 +3326,18 @@ write_label_prolog(pstops_doc_t *doc, /* { const char *classification; /* CLASSIFICATION environment variable */ @@ -1231,9 +1231,9 @@ diff -up cups-1.4.6/filter/pstops.c.lspp cups-1.4.6/filter/pstops.c /* -diff -up cups-1.4.6/Makedefs.in.lspp cups-1.4.6/Makedefs.in ---- cups-1.4.6/Makedefs.in.lspp 2011-01-14 17:14:06.310403173 +0000 -+++ cups-1.4.6/Makedefs.in 2011-01-14 17:14:06.431404614 +0000 +diff -urNp cups-1.4.6.old/Makedefs.in cups-1.4.6/Makedefs.in +--- cups-1.4.6.old/Makedefs.in 2011-03-07 13:34:53.424876279 +0000 ++++ cups-1.4.6/Makedefs.in 2011-03-07 13:35:07.145876086 +0000 @@ -146,7 +146,7 @@ LIBCUPSORDER = @LIBCUPSORDER@ LIBCUPSIMAGEORDER = @LIBCUPSIMAGEORDER@ LINKCUPS = @LINKCUPS@ $(SSLLIBS) $(DNSSDLIBS) @@ -1243,18 +1243,9 @@ diff -up cups-1.4.6/Makedefs.in.lspp cups-1.4.6/Makedefs.in OPTIM = @OPTIM@ OPTIONS = PAMLIBS = @PAMLIBS@ -@@ -258,7 +258,7 @@ DBUSDIR = @DBUSDIR@ - # Rules... - # - --.SILENT: -+ - .SUFFIXES: .1 .1.gz .1m .1m.gz .3 .3.gz .5 .5.gz .7 .7.gz .8 .8.gz .a .c .cxx .h .man .o .32.o .64.o .gz - - .c.o: -diff -up cups-1.4.6/scheduler/client.c.lspp cups-1.4.6/scheduler/client.c ---- cups-1.4.6/scheduler/client.c.lspp 2010-10-17 05:13:56.000000000 +0100 -+++ cups-1.4.6/scheduler/client.c 2011-01-14 17:14:06.437404687 +0000 +diff -urNp cups-1.4.6.old/scheduler/client.c cups-1.4.6/scheduler/client.c +--- cups-1.4.6.old/scheduler/client.c 2011-03-07 13:34:53.733876279 +0000 ++++ cups-1.4.6/scheduler/client.c 2011-03-07 13:35:07.150876188 +0000 @@ -44,6 +44,7 @@ * valid_host() - Is the Host: field valid? * write_file() - Send a file via HTTP. @@ -1475,9 +1466,9 @@ diff -up cups-1.4.6/scheduler/client.c.lspp cups-1.4.6/scheduler/client.c /* * 'pipe_command()' - Pipe the output of a command to the remote client. */ -diff -up cups-1.4.6/scheduler/client.h.lspp cups-1.4.6/scheduler/client.h ---- cups-1.4.6/scheduler/client.h.lspp 2009-05-26 23:01:23.000000000 +0100 -+++ cups-1.4.6/scheduler/client.h 2011-01-14 17:14:06.438404699 +0000 +diff -urNp cups-1.4.6.old/scheduler/client.h cups-1.4.6/scheduler/client.h +--- cups-1.4.6.old/scheduler/client.h 2011-03-07 13:34:53.708876279 +0000 ++++ cups-1.4.6/scheduler/client.h 2011-03-07 13:35:07.155876256 +0000 @@ -18,6 +18,13 @@ #endif /* HAVE_AUTHORIZATION_H */ @@ -1513,9 +1504,9 @@ diff -up cups-1.4.6/scheduler/client.h.lspp cups-1.4.6/scheduler/client.h /* -diff -up cups-1.4.6/scheduler/conf.c.lspp cups-1.4.6/scheduler/conf.c ---- cups-1.4.6/scheduler/conf.c.lspp 2011-01-14 17:14:06.148401242 +0000 -+++ cups-1.4.6/scheduler/conf.c 2011-01-14 17:14:06.442404747 +0000 +diff -urNp cups-1.4.6.old/scheduler/conf.c cups-1.4.6/scheduler/conf.c +--- cups-1.4.6.old/scheduler/conf.c 2011-03-07 13:34:53.540876279 +0000 ++++ cups-1.4.6/scheduler/conf.c 2011-03-07 13:35:07.157876274 +0000 @@ -29,6 +29,7 @@ * read_configuration() - Read a configuration file. * read_location() - Read a definition. @@ -1625,9 +1616,9 @@ diff -up cups-1.4.6/scheduler/conf.c.lspp cups-1.4.6/scheduler/conf.c /* * 'read_policy()' - Read a definition. -diff -up cups-1.4.6/scheduler/conf.h.lspp cups-1.4.6/scheduler/conf.h ---- cups-1.4.6/scheduler/conf.h.lspp 2011-01-14 17:14:06.149401254 +0000 -+++ cups-1.4.6/scheduler/conf.h 2011-01-14 17:14:06.444404768 +0000 +diff -urNp cups-1.4.6.old/scheduler/conf.h cups-1.4.6/scheduler/conf.h +--- cups-1.4.6.old/scheduler/conf.h 2011-03-07 13:34:53.561876277 +0000 ++++ cups-1.4.6/scheduler/conf.h 2011-03-07 13:35:07.158876277 +0000 @@ -250,6 +250,12 @@ VAR char *ServerKey VALUE(NULL); VAR int SSLOptions VALUE(CUPSD_SSL_NONE); /* SSL/TLS options */ @@ -1651,10 +1642,10 @@ diff -up cups-1.4.6/scheduler/conf.h.lspp cups-1.4.6/scheduler/conf.h /* * Prototypes... -diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c ---- cups-1.4.6/scheduler/ipp.c.lspp 2011-01-14 17:14:06.401404258 +0000 -+++ cups-1.4.6/scheduler/ipp.c 2011-01-14 17:14:06.454404890 +0000 -@@ -37,6 +37,7 @@ +diff -urNp cups-1.4.6.old/scheduler/ipp.c cups-1.4.6/scheduler/ipp.c +--- cups-1.4.6.old/scheduler/ipp.c 2011-03-07 13:34:53.720876279 +0000 ++++ cups-1.4.6/scheduler/ipp.c 2011-03-07 13:35:07.167876275 +0000 +@@ -41,6 +41,7 @@ * cancel_all_jobs() - Cancel all print jobs. * cancel_job() - Cancel a print job. * cancel_subscription() - Cancel a subscription. @@ -1662,7 +1653,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c * check_quotas() - Check quotas for a printer and user. * check_rss_recipient() - Check that we do not have a duplicate RSS * feed URI. -@@ -98,6 +99,9 @@ +@@ -102,6 +103,9 @@ * validate_user() - Validate the user for the request. */ @@ -1672,7 +1663,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * Include necessary headers... */ -@@ -118,6 +122,14 @@ extern int mbr_check_membership_by_id(uu +@@ -124,6 +128,14 @@ extern int mbr_check_membership_by_id(uu # endif /* HAVE_MEMBERSHIPPRIV_H */ #endif /* __APPLE__ */ @@ -1687,7 +1678,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * Local functions... -@@ -143,6 +155,9 @@ static void cancel_all_jobs(cupsd_client +@@ -157,6 +169,9 @@ static void cancel_all_jobs(cupsd_client static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri); static void cancel_subscription(cupsd_client_t *con, int id); static int check_rss_recipient(const char *recipient); @@ -1697,7 +1688,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p); static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr, int quickcopy); -@@ -1340,6 +1355,21 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1354,6 +1369,21 @@ add_job(cupsd_client_t *con, /* I - Cl ipp_attribute_t *media_col, /* media-col attribute */ *media_margin; /* media-*-margin attribute */ ipp_t *unsup_col; /* media-col in unsupported response */ @@ -1719,7 +1710,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", -@@ -1598,6 +1628,106 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1612,6 +1642,106 @@ add_job(cupsd_client_t *con, /* I - Cl ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled"); @@ -1826,7 +1817,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c if ((job = cupsdAddJob(priority, printer->name)) == NULL) { send_ipp_status(con, IPP_INTERNAL_ERROR, -@@ -1606,6 +1736,32 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1620,6 +1750,32 @@ add_job(cupsd_client_t *con, /* I - Cl return (NULL); } @@ -1859,7 +1850,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_REMOTE); job->attrs = con->request; -@@ -1811,6 +1967,29 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1825,6 +1981,29 @@ add_job(cupsd_client_t *con, /* I - Cl attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]); attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]); } @@ -1889,7 +1880,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c job->job_sheets = attr; -@@ -1841,6 +2020,9 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1855,6 +2034,9 @@ add_job(cupsd_client_t *con, /* I - Cl "job-sheets=\"%s,none\", " "job-originating-user-name=\"%s\"", Classification, job->username); @@ -1899,7 +1890,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c } else if (attr->num_values == 2 && strcmp(attr->values[0].string.text, -@@ -1859,6 +2041,9 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1873,6 +2055,9 @@ add_job(cupsd_client_t *con, /* I - Cl "job-originating-user-name=\"%s\"", attr->values[0].string.text, attr->values[1].string.text, job->username); @@ -1909,7 +1900,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c } else if (strcmp(attr->values[0].string.text, Classification) && strcmp(attr->values[0].string.text, "none") && -@@ -1879,6 +2064,9 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1893,6 +2078,9 @@ add_job(cupsd_client_t *con, /* I - Cl "job-originating-user-name=\"%s\"", attr->values[0].string.text, attr->values[1].string.text, job->username); @@ -1919,7 +1910,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c } } else if (strcmp(attr->values[0].string.text, Classification) && -@@ -1919,8 +2107,52 @@ add_job(cupsd_client_t *con, /* I - Cl +@@ -1933,8 +2121,52 @@ add_job(cupsd_client_t *con, /* I - Cl "job-sheets=\"%s\", " "job-originating-user-name=\"%s\"", Classification, job->username); @@ -1972,7 +1963,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * See if we need to add the starting sheet... -@@ -3726,6 +3958,107 @@ check_rss_recipient( +@@ -4295,6 +4527,107 @@ check_rss_recipient( } @@ -2080,7 +2071,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * 'check_quotas()' - Check quotas for a printer and user. */ -@@ -4280,6 +4613,15 @@ copy_banner(cupsd_client_t *con, /* I - +@@ -4849,6 +5182,15 @@ copy_banner(cupsd_client_t *con, /* I - char attrname[255], /* Name of attribute */ *s; /* Pointer into name */ ipp_attribute_t *attr; /* Attribute */ @@ -2096,7 +2087,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c cupsdLogMessage(CUPSD_LOG_DEBUG2, -@@ -4315,6 +4657,82 @@ copy_banner(cupsd_client_t *con, /* I - +@@ -4884,6 +5226,82 @@ copy_banner(cupsd_client_t *con, /* I - fchmod(cupsFileNumber(out), 0640); fchown(cupsFileNumber(out), RunUser, Group); @@ -2179,7 +2170,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * Try the localized banner file under the subdirectory... -@@ -4409,6 +4827,24 @@ copy_banner(cupsd_client_t *con, /* I - +@@ -4978,6 +5396,24 @@ copy_banner(cupsd_client_t *con, /* I - else s = attrname; @@ -2204,7 +2195,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c if (!strcmp(s, "printer-name")) { cupsFilePuts(out, job->dest); -@@ -6382,6 +6818,22 @@ get_job_attrs(cupsd_client_t *con, /* I +@@ -6957,6 +7393,22 @@ get_job_attrs(cupsd_client_t *con, /* I return; } @@ -2227,7 +2218,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * Copy attributes... */ -@@ -6612,6 +7064,11 @@ get_jobs(cupsd_client_t *con, /* I - C +@@ -7187,6 +7639,11 @@ get_jobs(cupsd_client_t *con, /* I - C if (username[0] && strcasecmp(username, job->username)) continue; @@ -2239,7 +2230,7 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c if (count > 0) ippAddSeparator(con->response); -@@ -11031,6 +11488,11 @@ validate_user(cupsd_job_t *job, /* I +@@ -11606,6 +12063,11 @@ validate_user(cupsd_job_t *job, /* I strlcpy(username, get_username(con), userlen); @@ -2251,9 +2242,9 @@ diff -up cups-1.4.6/scheduler/ipp.c.lspp cups-1.4.6/scheduler/ipp.c /* * Check the username against the owner... */ -diff -up cups-1.4.6/scheduler/job.c.lspp cups-1.4.6/scheduler/job.c ---- cups-1.4.6/scheduler/job.c.lspp 2011-01-14 17:14:06.262402601 +0000 -+++ cups-1.4.6/scheduler/job.c 2011-01-14 17:14:06.460404961 +0000 +diff -urNp cups-1.4.6.old/scheduler/job.c cups-1.4.6/scheduler/job.c +--- cups-1.4.6.old/scheduler/job.c 2011-03-07 13:34:53.553876279 +0000 ++++ cups-1.4.6/scheduler/job.c 2011-03-07 13:35:07.175876275 +0000 @@ -66,6 +66,9 @@ * update_job_attrs() - Update the job-printer-* attributes. */ @@ -2623,9 +2614,9 @@ diff -up cups-1.4.6/scheduler/job.c.lspp cups-1.4.6/scheduler/job.c /* * Now start the first file in the job... */ -diff -up cups-1.4.6/scheduler/job.h.lspp cups-1.4.6/scheduler/job.h ---- cups-1.4.6/scheduler/job.h.lspp 2009-05-11 23:46:01.000000000 +0100 -+++ cups-1.4.6/scheduler/job.h 2011-01-14 17:14:06.462404984 +0000 +diff -urNp cups-1.4.6.old/scheduler/job.h cups-1.4.6/scheduler/job.h +--- cups-1.4.6.old/scheduler/job.h 2011-03-07 13:34:53.530876279 +0000 ++++ cups-1.4.6/scheduler/job.h 2011-03-07 13:35:07.177876275 +0000 @@ -13,6 +13,13 @@ * file is missing or damaged, see the license at "http://www.cups.org/". */ @@ -2651,9 +2642,9 @@ diff -up cups-1.4.6/scheduler/job.h.lspp cups-1.4.6/scheduler/job.h }; typedef struct cupsd_joblog_s /**** Job log message ****/ -diff -up cups-1.4.6/scheduler/main.c.lspp cups-1.4.6/scheduler/main.c ---- cups-1.4.6/scheduler/main.c.lspp 2011-01-14 17:14:06.377403972 +0000 -+++ cups-1.4.6/scheduler/main.c 2011-01-14 17:14:06.465405021 +0000 +diff -urNp cups-1.4.6.old/scheduler/main.c cups-1.4.6/scheduler/main.c +--- cups-1.4.6.old/scheduler/main.c 2011-03-07 13:34:53.671876279 +0000 ++++ cups-1.4.6/scheduler/main.c 2011-03-07 13:35:07.179876275 +0000 @@ -37,6 +37,8 @@ * usage() - Show scheduler usage. */ @@ -2721,10 +2712,10 @@ diff -up cups-1.4.6/scheduler/main.c.lspp cups-1.4.6/scheduler/main.c return (!stop_scheduler); } -diff -up cups-1.4.6/scheduler/printers.c.lspp cups-1.4.6/scheduler/printers.c ---- cups-1.4.6/scheduler/printers.c.lspp 2011-01-14 17:14:06.411404377 +0000 -+++ cups-1.4.6/scheduler/printers.c 2011-01-14 17:14:54.854975766 +0000 -@@ -68,6 +68,8 @@ +diff -urNp cups-1.4.6.old/scheduler/printers.c cups-1.4.6/scheduler/printers.c +--- cups-1.4.6.old/scheduler/printers.c 2011-03-07 13:34:53.708876279 +0000 ++++ cups-1.4.6/scheduler/printers.c 2011-03-07 13:35:07.182876275 +0000 +@@ -59,6 +59,8 @@ * write_xml_string() - Write a string with XML escaping. */ @@ -2733,7 +2724,7 @@ diff -up cups-1.4.6/scheduler/printers.c.lspp cups-1.4.6/scheduler/printers.c /* * Include necessary headers... */ -@@ -94,6 +96,11 @@ +@@ -81,6 +83,11 @@ # include #endif /* HAVE_SYS_VFS_H */ @@ -2743,9 +2734,9 @@ diff -up cups-1.4.6/scheduler/printers.c.lspp cups-1.4.6/scheduler/printers.c +#endif /* WITH_LSPP */ + #ifdef HAVE_DBUS - # include - # ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND -@@ -2311,6 +2318,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) + # include "colord.h" + #endif /* HAVE_DBUS */ +@@ -2329,6 +2336,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) "username", "password" }; @@ -2759,7 +2750,7 @@ diff -up cups-1.4.6/scheduler/printers.c.lspp cups-1.4.6/scheduler/printers.c DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name, -@@ -2441,6 +2455,45 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) +@@ -2459,6 +2473,45 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p) attr->values[1].string.text = _cupsStrAlloc(Classification ? Classification : p->job_sheets[1]); } @@ -2805,7 +2796,7 @@ diff -up cups-1.4.6/scheduler/printers.c.lspp cups-1.4.6/scheduler/printers.c } p->raw = 0; -@@ -5588,7 +5641,6 @@ write_irix_state(cupsd_printer_t *p) /* +@@ -5605,7 +5658,6 @@ write_irix_state(cupsd_printer_t *p) /* } #endif /* __sgi */ diff --git a/cups.spec b/cups.spec index b868784..1a89973 100644 --- a/cups.spec +++ b/cups.spec @@ -13,7 +13,7 @@ Summary: Common Unix Printing System Name: cups Version: 1.4.6 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv2 Group: System Environment/Daemons Source: http://ftp.easysw.com/pub/cups/%{version}/cups-%{version}-source.tar.bz2 @@ -147,6 +147,9 @@ Requires: acl # Make sure we have some filters for converting to raster format. Requires: ghostscript-cups +# Make sure we register devices and profiles with colord. +Requires: colord + %package devel Summary: Common Unix Printing System - development environment Group: Development/Libraries @@ -607,6 +610,9 @@ rm -rf $RPM_BUILD_ROOT %{php_extdir}/phpcups.so %changelog +* Mon Mar 07 2011 Richard Hughes 1:1.4.6-13 +- Updated colord patch. + * Fri Feb 25 2011 Tim Waugh 1:1.4.6-12 - Fixed build failure due to php_zend_api macro type.