1786 lines
52 KiB
Diff
1786 lines
52 KiB
Diff
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 <cups/ppd-private.h>
|
|
|
|
#ifdef __APPLE__
|
|
# include <ApplicationServices/ApplicationServices.h>
|
|
-# include <CoreFoundation/CoreFoundation.h>
|
|
# ifdef HAVE_MEMBERSHIP_H
|
|
# include <membership.h>
|
|
# 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 <cups/ppd-private.h>
|
|
#include <cups/dir.h>
|
|
#ifdef HAVE_APPLICATIONSERVICES_H
|
|
# include <ApplicationServices/ApplicationServices.h>
|
|
#endif /* HAVE_APPLICATIONSERVICES_H */
|
|
+#ifdef __APPLE__
|
|
+# include <CoreFoundation/CoreFoundation.h>
|
|
+#endif /* __APPLE__ */
|
|
#ifdef HAVE_SYS_MOUNT_H
|
|
# include <sys/mount.h>
|
|
#endif /* HAVE_SYS_MOUNT_H */
|
|
@@ -81,6 +94,16 @@
|
|
# include <sys/vfs.h>
|
|
#endif /* HAVE_SYS_VFS_H */
|
|
|
|
+#ifdef HAVE_DBUS
|
|
+# include <dbus/dbus.h>
|
|
+# 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 */
|
|
+
|
|
|
|
/*
|
|
* 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
|
|
+ */
|
|
+
|
|
+ cupsdUnregisterColorProfiles(p);
|
|
+#endif /* HAVE_DBUS */
|
|
+
|
|
/*
|
|
* 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 */
|
|
+
|
|
/*
|
|
* 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.
|
|
+ */
|
|
+
|
|
+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));
|
|
+}
|
|
+#endif /* __APPLE__ */
|
|
+
|
|
+
|
|
+#if !defined(__APPLE__) && defined(HAVE_DBUS)
|
|
+/*
|
|
+ * 'dbus_profile_profile_set_property()' - Set a property on a profile
|
|
+ */
|
|
+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);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * 'dbus_profile_device_set_property()' - Set a property on a device
|
|
+ */
|
|
+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 */
|
|
+{
|
|
+ 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);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * 'dbus_create_profile()' - Create a color profile for a printer.
|
|
+ */
|
|
+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 */
|
|
+{
|
|
+ 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 */
|
|
+
|
|
+ /*
|
|
+ * Create the profile...
|
|
+ */
|
|
+
|
|
+ message = dbus_message_new_method_call("org.freedesktop.ColorManager",
|
|
+ "/org/freedesktop/ColorManager",
|
|
+ "org.freedesktop.ColorManager",
|
|
+ "CreateProfile");
|
|
+
|
|
+ dbus_message_append_iter_init(message, &args);
|
|
+ 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, "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);
|
|
+
|
|
+ /*
|
|
+ * Set the qualifier...
|
|
+ */
|
|
+ dbus_profile_profile_set_property (con, path, "Qualifier", qualifier);
|
|
+
|
|
+ /*
|
|
+ * 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);
|
|
+ free (idstr);
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * 'dbus_create_device()' - Create a device and register profiles.
|
|
+ */
|
|
+
|
|
+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 */
|
|
+{
|
|
+ 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 */
|
|
+
|
|
+ /*
|
|
+ * 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))
|
|
+ {
|
|
+ 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);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Set the default profile
|
|
+ */
|
|
+ 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;
|
|
+
|
|
+ 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);
|
|
+
|
|
+
|
|
+ /*
|
|
+ * 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);
|
|
+
|
|
+out:
|
|
+ free(default_profile_path);
|
|
+ free(device_path);
|
|
+// dbus_message_unref(message);
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * 'dbus_delete_device_and_profiles()' - Delete previously registered
|
|
+ * color device and profiles
|
|
+ */
|
|
+
|
|
+static void
|
|
+dbus_delete_device_and_profiles(cupsd_printer_t *p) /* I - Printer */
|
|
+{
|
|
+ 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;
|
|
+
|
|
+ /*
|
|
+ * 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
|
|
+ */
|
|
+
|
|
+ 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
|
|
+ {
|
|
+ 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.
|
|
+ */
|
|
+
|
|
+
|
|
+out:
|
|
+ for (profile_path = cupsArrayFirst(profile_paths);
|
|
+ profile_path;
|
|
+ profile_path = cupsArrayNext(profile_paths))
|
|
+ free (profile_path);
|
|
+
|
|
+ cupsArrayDelete(profile_paths);
|
|
+ dbus_message_unref(message);
|
|
+ dbus_connection_unref(con);
|
|
+}
|
|
+#endif /* !defined(__APPLE__) && defined(HAVE_DBUS) */
|
|
+
|
|
+
|
|
+/*
|
|
+ * 'cupsdRegisterColorProfiles()' - Register color profiles for a printer.
|
|
+ */
|
|
+
|
|
+void
|
|
+cupsdRegisterColorProfiles(
|
|
+ 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 */
|
|
+
|
|
+
|
|
+#ifdef __APPLE__
|
|
+ /*
|
|
+ * Make sure ColorSync is available...
|
|
+ */
|
|
+
|
|
+ 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) */
|
|
+
|
|
+ /*
|
|
+ * 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)
|
|
+ {
|
|
+#ifdef __APPLE__
|
|
+ default_profile_id = atoi(attr->value);
|
|
+#elif HAVE_DBUS
|
|
+ default_profile_id = attr->value;
|
|
+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */
|
|
+ }
|
|
+
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+#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));
|
|
+
|
|
+ if (access(iccfile, 0))
|
|
+ continue;
|
|
+
|
|
+#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;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+#ifdef __APPLE__
|
|
+ _ppdFreeLanguages(languages);
|
|
+#endif /* __APPLE__ */
|
|
+ }
|
|
+ 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;
|
|
+
|
|
+#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;
|
|
+ }
|
|
+
|
|
+ profiles->profileCount = num_profiles;
|
|
+ profile = profiles->profiles;
|
|
+#endif /* __APPLE__ */
|
|
+
|
|
+ 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";
|
|
+
|
|
+ snprintf(selector, sizeof(selector), "%s..", profile_name);
|
|
+
|
|
+#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;
|
|
+ }
|
|
+ }
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ profiles->profileCount = num_profiles;
|
|
+
|
|
+ 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) */
|
|
+
|
|
+ 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;
|
|
+
|
|
+ case PPD_CS_GRAY :
|
|
+ if (attr)
|
|
+ break;
|
|
+
|
|
+ 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) */
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (num_profiles > 0)
|
|
+ {
|
|
+ /*
|
|
+ * Make sure we have a default profile 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__ */
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Get the device ID hash and pathelogical name dictionary.
|
|
+ */
|
|
+
|
|
+ cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"",
|
|
+ p->name);
|
|
+
|
|
+#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...
|
|
+ */
|
|
+
|
|
+ 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;
|
|
+#elif defined(HAVE_DBUS)
|
|
+ dbus_create_device (con, p, profiles, default_profile_id);
|
|
+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */
|
|
+
|
|
+ /*
|
|
+ * Clean up...
|
|
+ */
|
|
+
|
|
+#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) */
|
|
+ }
|
|
+
|
|
+ ppdClose(ppd);
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * 'cupsdUnregisterColorProfiles()' - Remove color profiles for the specified
|
|
+ * printer.
|
|
+ */
|
|
+
|
|
+void
|
|
+cupsdUnregisterColorProfiles(
|
|
+ cupsd_printer_t *p) /* I - Printer */
|
|
+{
|
|
+#ifdef __APPLE__
|
|
+ /*
|
|
+ * Make sure ColorSync is available...
|
|
+ */
|
|
+
|
|
+ if (CMUnregisterColorDevice != NULL)
|
|
+ CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name));
|
|
+#elif defined(HAVE_DBUS)
|
|
+ dbus_delete_device_and_profiles (p);
|
|
+#endif /* defined(__APPLE__) || defined(HAVE_DBUS) */
|
|
+}
|
|
+
|
|
+
|
|
/*
|
|
* 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
|
|
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);
|
|
|
|
|
|
/*
|