]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
First pass on unifying the IPP and PPD cache - rename and move PPD caching
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Sat, 12 Mar 2011 22:33:41 +0000 (22:33 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Sat, 12 Mar 2011 22:33:41 +0000 (22:33 +0000)
functions.

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@9600 7a7537e8-13f0-0310-91df-b6672ffda945

13 files changed:
backend/ipp.c
cups/Makefile
cups/mark.c
cups/ppd-cache.c [moved from cups/pwg-ppd.c with 53% similarity]
cups/ppd-private.h
cups/ppd.c
cups/ppd.h
cups/pwg-file.c [deleted file]
cups/testpwg.c
scheduler/ipp.c
scheduler/job.c
scheduler/printers.c
scheduler/printers.h

index 274e675fba1c2e910bf0869b839636b2af1ee0e6..e1d584dbdc142c16286161ffe9576c8059dc53ea 100644 (file)
@@ -115,7 +115,7 @@ static ipp_t                *new_request(ipp_op_t op, int version, const char *uri,
                                     const char *user, const char *title,
                                     int num_options, cups_option_t *options,
                                     const char *compression, int copies,
-                                    const char *format, _pwg_t *pwg,
+                                    const char *format, _ppd_cache_t *pc,
                                     ipp_attribute_t *media_col_sup);
 static const char      *password_cb(const char *);
 static void            report_attr(ipp_attribute_t *attr);
@@ -198,7 +198,7 @@ main(int  argc,                             /* I - Number of command-line args */
 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
   int          version;                /* IPP version */
   ppd_file_t   *ppd;                   /* PPD file */
-  _pwg_t       *pwg;                   /* PWG<->PPD mapping data */
+  _ppd_cache_t *pc;                    /* PPD cache and mapping data */
 
 
  /*
@@ -956,7 +956,7 @@ main(int  argc,                             /* I - Number of command-line args */
   */
 
   options = NULL;
-  pwg     = NULL;
+  p     = NULL;
 
   if (send_options)
   {
@@ -969,7 +969,7 @@ main(int  argc,                             /* I - Number of command-line args */
       */
 
       ppd = ppdOpenFile(getenv("PPD"));
-      pwg = _pwgCreateWithPPD(ppd);
+      pc  = _ppdCacheCreateWithPPD(ppd);
 
       ppdClose(ppd);
     }
@@ -1025,7 +1025,7 @@ main(int  argc,                           /* I - Number of command-line args */
   {
     request = new_request(IPP_VALIDATE_JOB, version, uri, argv[2], argv[3],
                           num_options, options, compression,
-                         copies_sup ? copies : 1, document_format, pwg,
+                         copies_sup ? copies : 1, document_format, pc,
                          media_col_sup);
 
     ippDelete(cupsDoRequest(http, request, resource));
@@ -1101,7 +1101,7 @@ main(int  argc,                           /* I - Number of command-line args */
     request = new_request(num_files > 1 ? IPP_CREATE_JOB : IPP_PRINT_JOB,
                          version, uri, argv[2], argv[3], num_options, options,
                          compression, copies_sup ? copies : 1, document_format,
-                         pwg, media_col_sup);
+                         pc, media_col_sup);
 
    /*
     * Do the request...
@@ -1448,7 +1448,7 @@ main(int  argc,                           /* I - Number of command-line args */
   cleanup:
 
   cupsFreeOptions(num_options, options);
-  _pwgDestroy(pwg);
+  _ppdCacheDestroy(pc);
 
   httpClose(http);
 
@@ -1671,8 +1671,7 @@ monitor_printer(
                *response;              /* IPP response */
   ipp_attribute_t *attr;               /* Attribute in response */
   int          delay,                  /* Current delay */
-               prev_delay,             /* Previous delay */
-               temp_delay;             /* Temporary delay value */
+               prev_delay;             /* Previous delay */
 
 
  /*
@@ -1787,7 +1786,7 @@ new_request(
     const char      *compression,      /* I - compression value or NULL */
     int             copies,            /* I - copies value or 0 */
     const char      *format,           /* I - documet-format value or NULL */
-    _pwg_t          *pwg,              /* I - PWG<->PPD mapping data */
+    _ppd_cache_t    *pc,               /* I - PPD cache and mapping data */
     ipp_attribute_t *media_col_sup)    /* I - media-col-supported values */
 {
   int          i;                      /* Looping var */
@@ -1857,7 +1856,7 @@ new_request(
 
   if (num_options > 0)
   {
-    if (pwg)
+    if (pc)
     {
      /*
       * Send standard IPP attributes...
@@ -1866,7 +1865,7 @@ new_request(
       if ((keyword = cupsGetOption("PageSize", num_options, options)) == NULL)
        keyword = cupsGetOption("media", num_options, options);
 
-      if ((size = _pwgGetSize(pwg, keyword)) != NULL)
+      if ((size = _ppdCacheGetSize(pc, keyword)) != NULL)
       {
        /*
         * Add a media-col value...
@@ -1881,11 +1880,12 @@ new_request(
        media_col = ippNew();
        ippAddCollection(media_col, IPP_TAG_ZERO, "media-size", media_size);
 
-       media_source = _pwgGetSource(pwg, cupsGetOption("InputSlot",
-                                                       num_options,
-                                                       options));
-       media_type   = _pwgGetType(pwg, cupsGetOption("MediaType",
-                                                     num_options, options));
+       media_source = _ppdCacheGetSource(pc, cupsGetOption("InputSlot",
+                                                           num_options,
+                                                           options));
+       media_type   = _ppdCacheGetType(pc, cupsGetOption("MediaType",
+                                                         num_options,
+                                                         options));
 
        for (i = 0; i < media_col_sup->num_values; i ++)
        {
@@ -1920,8 +1920,8 @@ new_request(
 
       if ((keyword = cupsGetOption("output-bin", num_options,
                                   options)) == NULL)
-       keyword = _pwgGetBin(pwg, cupsGetOption("OutputBin", num_options,
-                                               options));
+       keyword = _ppdCacheGetBin(pc, cupsGetOption("OutputBin", num_options,
+                                                   options));
 
       if (keyword)
        ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "output-bin",
@@ -1963,17 +1963,17 @@ new_request(
       if ((keyword = cupsGetOption("sides", num_options, options)) != NULL)
        ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides",
                     NULL, keyword);
-      else if (pwg->sides_option &&
-               (keyword = cupsGetOption(pwg->sides_option, num_options,
+      else if (pc->sides_option &&
+               (keyword = cupsGetOption(pc->sides_option, num_options,
                                        options)) != NULL)
       {
-       if (!strcasecmp(keyword, pwg->sides_1sided))
+       if (!strcasecmp(keyword, pc->sides_1sided))
          ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides",
                       NULL, "one-sided");
-       else if (!strcasecmp(keyword, pwg->sides_2sided_long))
+       else if (!strcasecmp(keyword, pc->sides_2sided_long))
          ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides",
                       NULL, "two-sided-long-edge");
-       if (!strcasecmp(keyword, pwg->sides_2sided_short))
+       if (!strcasecmp(keyword, pc->sides_2sided_short))
          ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "sides",
                       NULL, "two-sided-short-edge");
       }
index 14441917c4e8029f20715a2a8b9b715940106d78..ae62f187dff77d288fb33fa3ab4da2631a3b024c 100644 (file)
@@ -56,9 +56,8 @@ LIBOBJS       =       \
                options.o \
                page.o \
                ppd.o \
-               pwg-file.o \
+               ppd-cache.o \
                pwg-media.o \
-               pwg-ppd.o \
                request.o \
                sidechannel.o \
                snmp.o \
index be5832ed766a8a6323c4a5c802f914a3588b151d..cca9d013645b1cf9abcba0aaacd7c0f6d519362f 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   Option marking routines for CUPS.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
@@ -62,8 +62,9 @@ static void   ppd_mark_option(ppd_file_t *ppd, const char *option,
  * 'cupsMarkOptions()' - Mark command-line options in a PPD file.
  *
  * This function maps the IPP "finishings", "media", "mirror",
- * "multiple-document-handling", "output-bin", "printer-resolution", and
- * "sides" attributes to their corresponding PPD options and choices.
+ * "multiple-document-handling", "output-bin", "print-color-mode",
+ * "print-quality", "printer-resolution", and "sides" attributes to their
+ * corresponding PPD options and choices.
  */
 
 int                                    /* O - 1 if conflicts exist, 0 otherwise */
@@ -78,14 +79,14 @@ cupsMarkOptions(
   const char   *val,                   /* Pointer into value */
                *media,                 /* media option */
                *output_bin,            /* output-bin option */
-               *output_mode,           /* output-mode option */
                *page_size,             /* PageSize option */
                *ppd_keyword,           /* PPD keyword */
+               *print_color_mode,      /* print-color-mode option */
                *print_quality,         /* print-quality option */
                *sides;                 /* sides option */
   cups_option_t        *optptr;                /* Current option */
   ppd_attr_t   *attr;                  /* PPD attribute */
-  _pwg_t       *pwg;                   /* PWG mapping data */
+  _ppd_cache_t *cache;                 /* PPD cache and mapping data */
 
 
  /*
@@ -104,22 +105,25 @@ cupsMarkOptions(
 
   media         = cupsGetOption("media", num_options, options);
   output_bin    = cupsGetOption("output-bin", num_options, options);
-  output_mode   = cupsGetOption("output-mode", num_options, options);
   page_size     = cupsGetOption("PageSize", num_options, options);
   print_quality = cupsGetOption("print-quality", num_options, options);
   sides         = cupsGetOption("sides", num_options, options);
 
-  if ((media || output_bin || output_mode || print_quality || sides) &&
-      !ppd->pwg)
+  if ((print_color_mode = cupsGetOption("print-color-mode", num_options,
+                                        options)) == NULL)
+    print_color_mode = cupsGetOption("output-mode", num_options, options);
+
+  if ((media || output_bin || print_color_mode || print_quality || sides) &&
+      !ppd->cache)
   {
    /*
-    * Load PWG mapping data as needed...
+    * Load PPD cache and mapping data as needed...
     */
 
-    ppd->pwg = _pwgCreateWithPPD(ppd);
+    ppd->cache = _ppdCacheCreateWithPPD(ppd);
   }
 
-  pwg = (_pwg_t *)ppd->pwg;
+  cache = ppd->cache;
 
   if (media)
   {
@@ -154,40 +158,40 @@ cupsMarkOptions(
       {
         if (!strncasecmp(s, "Custom.", 7) || ppdPageSize(ppd, s))
           ppd_mark_option(ppd, "PageSize", s);
-        else if ((ppd_keyword = _pwgGetPageSize(pwg, NULL, s, NULL)) != NULL)
+        else if ((ppd_keyword = _ppdCacheGetPageSize(cache, NULL, s, NULL)) != NULL)
          ppd_mark_option(ppd, "PageSize", ppd_keyword);
       }
 
-      if (pwg && pwg->source_option &&
-          !cupsGetOption(pwg->source_option, num_options, options) &&
-         (ppd_keyword = _pwgGetInputSlot(pwg, NULL, s)) != NULL)
-       ppd_mark_option(ppd, pwg->source_option, ppd_keyword);
+      if (cache && cache->source_option &&
+          !cupsGetOption(cache->source_option, num_options, options) &&
+         (ppd_keyword = _ppdCacheGetInputSlot(cache, NULL, s)) != NULL)
+       ppd_mark_option(ppd, cache->source_option, ppd_keyword);
 
       if (!cupsGetOption("MediaType", num_options, options) &&
-         (ppd_keyword = _pwgGetMediaType(pwg, NULL, s)) != NULL)
+         (ppd_keyword = _ppdCacheGetMediaType(cache, NULL, s)) != NULL)
        ppd_mark_option(ppd, "MediaType", ppd_keyword);
     }
   }
 
-  if (pwg)
+  if (cache)
   {
     if (!cupsGetOption("com.apple.print.DocumentTicket.PMSpoolFormat",
                        num_options, options) &&
         !cupsGetOption("APPrinterPreset", num_options, options) &&
-        (output_mode || print_quality))
+        (print_color_mode || print_quality))
     {
      /*
       * Map output-mode and print-quality to a preset...
       */
 
-      _pwg_output_mode_t       pwg_om; /* output-mode index */
+      _pwg_print_color_mode_t  pwg_pcm;/* print-color-mode index */
       _pwg_print_quality_t     pwg_pq; /* print-quality index */
       cups_option_t            *preset;/* Current preset option */
 
-      if (output_mode && !strcmp(output_mode, "monochrome"))
-       pwg_om = _PWG_OUTPUT_MODE_MONOCHROME;
+      if (print_color_mode && !strcmp(print_color_mode, "monochrome"))
+       pwg_pcm = _PWG_PRINT_COLOR_MODE_MONOCHROME;
       else
-       pwg_om = _PWG_OUTPUT_MODE_COLOR;
+       pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR;
 
       if (print_quality)
       {
@@ -200,33 +204,33 @@ cupsMarkOptions(
       else
        pwg_pq = _PWG_PRINT_QUALITY_NORMAL;
 
-      if (pwg->num_presets[pwg_om][pwg_pq] == 0)
+      if (cache->num_presets[pwg_pcm][pwg_pq] == 0)
       {
        /*
        * Try to find a preset that works so that we maximize the chances of us
        * getting a good print using IPP attributes.
        */
 
-       if (pwg->num_presets[pwg_om][_PWG_PRINT_QUALITY_NORMAL] > 0)
+       if (cache->num_presets[pwg_pcm][_PWG_PRINT_QUALITY_NORMAL] > 0)
          pwg_pq = _PWG_PRINT_QUALITY_NORMAL;
-       else if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_pq] > 0)
-         pwg_om = _PWG_OUTPUT_MODE_COLOR;
+       else if (cache->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][pwg_pq] > 0)
+         pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR;
        else
        {
-         pwg_pq = _PWG_PRINT_QUALITY_NORMAL;
-         pwg_om = _PWG_OUTPUT_MODE_COLOR;
+         pwg_pq  = _PWG_PRINT_QUALITY_NORMAL;
+         pwg_pcm = _PWG_PRINT_COLOR_MODE_COLOR;
        }
       }
 
-      if (pwg->num_presets[pwg_om][pwg_pq] > 0)
+      if (cache->num_presets[pwg_pcm][pwg_pq] > 0)
       {
        /*
        * Copy the preset options as long as the corresponding names are not
        * already defined in the IPP request...
        */
 
-       for (i = pwg->num_presets[pwg_om][pwg_pq],
-                preset = pwg->presets[pwg_om][pwg_pq];
+       for (i = cache->num_presets[pwg_pcm][pwg_pq],
+                preset = cache->presets[pwg_pcm][pwg_pq];
             i > 0;
             i --, preset ++)
        {
@@ -237,7 +241,7 @@ cupsMarkOptions(
     }
 
     if (output_bin && !cupsGetOption("OutputBin", num_options, options) &&
-       (ppd_keyword = _pwgGetOutputBin(pwg, output_bin)) != NULL) 
+       (ppd_keyword = _ppdCacheGetOutputBin(cache, output_bin)) != NULL) 
     {
      /*
       * Map output-bin to OutputBin...
@@ -246,19 +250,19 @@ cupsMarkOptions(
       ppd_mark_option(ppd, "OutputBin", ppd_keyword);
     }
 
-    if (sides && pwg->sides_option &&
-        !cupsGetOption(pwg->sides_option, num_options, options))
+    if (sides && cache->sides_option &&
+        !cupsGetOption(cache->sides_option, num_options, options))
     {
      /*
       * Map sides to duplex option...
       */
 
       if (!strcmp(sides, "one-sided"))
-        ppd_mark_option(ppd, pwg->sides_option, pwg->sides_1sided);
+        ppd_mark_option(ppd, cache->sides_option, cache->sides_1sided);
       else if (!strcmp(sides, "two-sided-long-edge"))
-        ppd_mark_option(ppd, pwg->sides_option, pwg->sides_2sided_long);
+        ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_long);
       else if (!strcmp(sides, "two-sided-short-edge"))
-        ppd_mark_option(ppd, pwg->sides_option, pwg->sides_2sided_short);
+        ppd_mark_option(ppd, cache->sides_option, cache->sides_2sided_short);
     }
   }
 
similarity index 53%
rename from cups/pwg-ppd.c
rename to cups/ppd-cache.c
index 0fd81d82abbfdb62f4bb4056f57ca64f18436569..f9f966f3538715a16d37de28640abd0f40e48c3e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * "$Id$"
  *
- *   PWG PPD mapping API implementation for CUPS.
+ *   PPD cache implementation for CUPS.
  *
  *   Copyright 2010-2011 by Apple Inc.
  *
  *
  * Contents:
  *
- *   _pwgCreateWithPPD()      - Create PWG mapping data from a PPD file.
- *   _pwgGetBin()             - Get the PWG output-bin keyword associated with a
- *                              PPD OutputBin.
- *   _pwgGetInputSlot()       - Get the PPD InputSlot associated with the job
- *                              attributes or a keyword string.
- *   _pwgGetMediaType()       - Get the PPD MediaType associated with the job
- *                              attributes or a keyword string.
- *   _pwgGetOutputBin()       - Get the PPD OutputBin associated with the
- *                              keyword string.
- *   _pwgGetPageSize()        - Get the PPD PageSize associated with the job
- *                              attributes or a keyword string.
- *   _pwgGetSize()            - Get the PWG size associated with a PPD PageSize.
- *   _pwgGetSource()          - Get the PWG media-source associated with a PPD
- *                              InputSlot.
- *   _pwgGetType()            - Get the PWG media-type associated with a PPD
- *                              MediaType.
- *   _pwgInputSlotForSource() - Get the InputSlot name for the given PWG source.
- *   _pwgMediaTypeForType()   - Get the MediaType name for the given PWG type.
- *   _pwgPageSizeForMedia()   - Get the PageSize name for the given media.
- *   pwg_ppdize_name()        - Convert an IPP keyword to a PPD keyword.
- *   pwg_unppdize_name()      - Convert a PPD keyword to a lowercase IPP
- *                              keyword.
+ *   _ppdCacheCreateWithFile()     - Create PWG mapping data from a written
+ *                                   file.
+ *   _ppdCacheCreateWithPPD()      - Create PWG mapping data from a PPD file.
+ *   _ppdCacheDestroy()            - Free all memory used for PWG mapping data.
+ *   _ppdCacheGetBin()             - Get the PWG output-bin keyword associated
+ *                                   with a PPD OutputBin.
+ *   _ppdCacheGetInputSlot()       - Get the PPD InputSlot associated with the
+ *                                   job attributes or a keyword string.
+ *   _ppdCacheGetMediaType()       - Get the PPD MediaType associated with the
+ *                                   job attributes or a keyword string.
+ *   _ppdCacheGetOutputBin()       - Get the PPD OutputBin associated with the
+ *                                   keyword string.
+ *   _ppdCacheGetPageSize()        - Get the PPD PageSize associated with the
+ *                                   job attributes or a keyword string.
+ *   _ppdCacheGetSize()            - Get the PWG size associated with a PPD
+ *                                   PageSize.
+ *   _ppdCacheGetSource()          - Get the PWG media-source associated with a
+ *                                   PPD InputSlot.
+ *   _ppdCacheGetType()            - Get the PWG media-type associated with a
+ *                                   PPD MediaType.
+ *   _pwgInputSlotForSource() - Get the InputSlot name for the given PWG
+ *                                   source.
+ *   _pwgMediaTypeForType()   - Get the MediaType name for the given PWG
+ *                                   type.
+ *   _ppdCacheWriteFile()          - Write PWG mapping data to a file.
+ *   _pwgPageSizeForMedia()        - Get the PageSize name for the given media.
+ *   pwg_ppdize_name()             - Convert an IPP keyword to a PPD keyword.
+ *   pwg_unppdize_name()           - Convert a PPD keyword to a lowercase IPP
+ *                                   keyword.
  */
 
 /*
@@ -63,14 +70,415 @@ static void        pwg_unppdize_name(const char *ppd, char *name, size_t namesize);
 
 
 /*
- * '_pwgCreateWithPPD()' - Create PWG mapping data from a PPD file.
+ * '_ppdCacheCreateWithFile()' - Create PWG mapping data from a written file.
+ *
+ * Use the @link _ppdCacheWriteFile@ function to write PWG mapping data to a file.
+ */
+
+_ppd_cache_t *                         /* O - PPD cache and mapping data */
+_ppdCacheCreateWithFile(
+    const char *filename)              /* I - File to read */
+{
+  cups_file_t  *fp;                    /* File */
+  _ppd_cache_t *pc;                    /* PWG mapping data */
+  _pwg_size_t  *size;                  /* Current size */
+  _pwg_map_t   *map;                   /* Current map */
+  int          linenum,                /* Current line number */
+               num_bins,               /* Number of bins in file */
+               num_sizes,              /* Number of sizes in file */
+               num_sources,            /* Number of sources in file */
+               num_types;              /* Number of types in file */
+  char         line[2048],             /* Current line */
+               *value,                 /* Pointer to value in line */
+               *valueptr,              /* Pointer into value */
+               pwg_keyword[128],       /* PWG keyword */
+               ppd_keyword[PPD_MAX_NAME];
+                                       /* PPD keyword */
+  _pwg_print_color_mode_t print_color_mode;
+                                       /* Print color mode for preset */
+  _pwg_print_quality_t print_quality;  /* Print quality for preset */
+
+
+  DEBUG_printf(("_ppdCacheCreateWithFile(filename=\"%s\")", filename));
+
+ /*
+  * Range check input...
+  */
+
+  if (!filename)
+  {
+    _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
+    return (NULL);
+  }
+
+ /*
+  * Open the file...
+  */
+
+  if ((fp = cupsFileOpen(filename, "r")) == NULL)
+  {
+    _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+    return (NULL);
+  }
+
+ /*
+  * Allocate the mapping data structure...
+  */
+
+  if ((pc = calloc(1, sizeof(_ppd_cache_t))) == NULL)
+  {
+    DEBUG_puts("_ppdCacheCreateWithFile: Unable to allocate _ppd_cache_t.");
+    _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+    goto create_error;
+  }
+
+ /*
+  * Read the file...
+  */
+
+  linenum     = 0;
+  num_bins    = 0;
+  num_sizes   = 0;
+  num_sources = 0;
+  num_types   = 0;
+
+  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+  {
+    DEBUG_printf(("_ppdCacheCreateWithFile: line=\"%s\", value=\"%s\", "
+                  "linenum=%d", line, value, linenum));
+
+    if (!value)
+    {
+      DEBUG_printf(("_ppdCacheCreateWithFile: Missing value on line %d.",
+                    linenum));
+      _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+      goto create_error;
+    }
+    else if (!strcasecmp(line, "NumBins"))
+    {
+      if (num_bins > 0)
+      {
+        DEBUG_puts("_ppdCacheCreateWithFile: NumBins listed multiple times.");
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((num_bins = atoi(value)) <= 0 || num_bins > 65536)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumBins value %d on line "
+                     "%d.", num_sizes, linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((pc->bins = calloc(num_bins, sizeof(_pwg_map_t))) == NULL)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d bins.",
+                     num_sizes));
+       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+       goto create_error;
+      }
+    }
+    else if (!strcasecmp(line, "Bin"))
+    {
+      if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad Bin on line %d.", linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if (pc->num_bins >= num_bins)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Too many Bin's on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      map      = pc->bins + pc->num_bins;
+      map->pwg = _cupsStrAlloc(pwg_keyword);
+      map->ppd = _cupsStrAlloc(ppd_keyword);
+
+      pc->num_bins ++;
+    }
+    else if (!strcasecmp(line, "NumSizes"))
+    {
+      if (num_sizes > 0)
+      {
+        DEBUG_puts("_ppdCacheCreateWithFile: NumSizes listed multiple times.");
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSizes value %d on line "
+                     "%d.", num_sizes, linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((pc->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sizes.",
+                     num_sizes));
+       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+       goto create_error;
+      }
+    }
+    else if (!strcasecmp(line, "Size"))
+    {
+      if (pc->num_sizes >= num_sizes)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Too many Size's on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      size = pc->sizes + pc->num_sizes;
+
+      if (sscanf(value, "%127s%40s%d%d%d%d%d%d", pwg_keyword, ppd_keyword,
+                &(size->width), &(size->length), &(size->left),
+                &(size->bottom), &(size->right), &(size->top)) != 8)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad Size on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      size->map.pwg = _cupsStrAlloc(pwg_keyword);
+      size->map.ppd = _cupsStrAlloc(ppd_keyword);
+
+      pc->num_sizes ++;
+    }
+    else if (!strcasecmp(line, "CustomSize"))
+    {
+      if (pc->custom_max_width > 0)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Too many CustomSize's on line "
+                     "%d.", linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if (sscanf(value, "%d%d%d%d%d%d%d%d", &(pc->custom_max_width),
+                 &(pc->custom_max_length), &(pc->custom_min_width),
+                &(pc->custom_min_length), &(pc->custom_size.left),
+                &(pc->custom_size.bottom), &(pc->custom_size.right),
+                &(pc->custom_size.top)) != 8)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad CustomSize on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
+                      pc->custom_max_width, pc->custom_max_length);
+      pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
+
+      _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
+                      pc->custom_min_width, pc->custom_min_length);
+      pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
+    }
+    else if (!strcasecmp(line, "SourceOption"))
+    {
+      pc->source_option = _cupsStrAlloc(value);
+    }
+    else if (!strcasecmp(line, "NumSources"))
+    {
+      if (num_sources > 0)
+      {
+        DEBUG_puts("_ppdCacheCreateWithFile: NumSources listed multiple "
+                  "times.");
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((num_sources = atoi(value)) <= 0 || num_sources > 65536)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumSources value %d on "
+                     "line %d.", num_sources, linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((pc->sources = calloc(num_sources, sizeof(_pwg_map_t))) == NULL)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d sources.",
+                     num_sources));
+       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+       goto create_error;
+      }
+    }
+    else if (!strcasecmp(line, "Source"))
+    {
+      if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad Source on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if (pc->num_sources >= num_sources)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Too many Source's on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      map      = pc->sources + pc->num_sources;
+      map->pwg = _cupsStrAlloc(pwg_keyword);
+      map->ppd = _cupsStrAlloc(ppd_keyword);
+
+      pc->num_sources ++;
+    }
+    else if (!strcasecmp(line, "NumTypes"))
+    {
+      if (num_types > 0)
+      {
+        DEBUG_puts("_ppdCacheCreateWithFile: NumTypes listed multiple times.");
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((num_types = atoi(value)) <= 0 || num_types > 65536)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad NumTypes value %d on "
+                     "line %d.", num_types, linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if ((pc->types = calloc(num_types, sizeof(_pwg_map_t))) == NULL)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Unable to allocate %d types.",
+                     num_types));
+       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+       goto create_error;
+      }
+    }
+    else if (!strcasecmp(line, "Type"))
+    {
+      if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad Type on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      if (pc->num_types >= num_types)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Too many Type's on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      map      = pc->types + pc->num_types;
+      map->pwg = _cupsStrAlloc(pwg_keyword);
+      map->ppd = _cupsStrAlloc(ppd_keyword);
+
+      pc->num_types ++;
+    }
+    else if (!strcasecmp(line, "Preset"))
+    {
+     /*
+      * Preset output-mode print-quality name=value ...
+      */
+
+      print_color_mode = (_pwg_print_color_mode_t)strtol(value, &valueptr, 10);
+      print_quality    = (_pwg_print_quality_t)strtol(valueptr, &valueptr, 10);
+
+      if (print_color_mode < _PWG_PRINT_COLOR_MODE_MONOCHROME ||
+          print_color_mode >= _PWG_PRINT_COLOR_MODE_MAX ||
+         print_quality < _PWG_PRINT_QUALITY_DRAFT ||
+         print_quality >= _PWG_PRINT_QUALITY_MAX ||
+         valueptr == value || !*valueptr)
+      {
+        DEBUG_printf(("_ppdCacheCreateWithFile: Bad Preset on line %d.",
+                     linenum));
+       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+       goto create_error;
+      }
+
+      pc->num_presets[print_color_mode][print_quality] =
+          cupsParseOptions(valueptr, 0,
+                          pc->presets[print_color_mode] + print_quality);
+    }
+    else if (!strcasecmp(line, "SidesOption"))
+      pc->sides_option = _cupsStrAlloc(value);
+    else if (!strcasecmp(line, "Sides1Sided"))
+      pc->sides_1sided = _cupsStrAlloc(value);
+    else if (!strcasecmp(line, "Sides2SidedLong"))
+      pc->sides_2sided_long = _cupsStrAlloc(value);
+    else if (!strcasecmp(line, "Sides2SidedShort"))
+      pc->sides_2sided_short = _cupsStrAlloc(value);
+    else
+    {
+      DEBUG_printf(("_ppdCacheCreateWithFile: Unknown %s on line %d.", line,
+                   linenum));
+      _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+      goto create_error;
+    }
+  }
+
+  if (pc->num_sizes < num_sizes)
+  {
+    DEBUG_printf(("_ppdCacheCreateWithFile: Not enough sizes (%d < %d).",
+                  pc->num_sizes, num_sizes));
+    _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+    goto create_error;
+  }
+
+  if (pc->num_sources < num_sources)
+  {
+    DEBUG_printf(("_ppdCacheCreateWithFile: Not enough sources (%d < %d).",
+                  pc->num_sources, num_sources));
+    _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+    goto create_error;
+  }
+
+  if (pc->num_types < num_types)
+  {
+    DEBUG_printf(("_ppdCacheCreateWithFile: Not enough types (%d < %d).",
+                  pc->num_types, num_types));
+    _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PPD cache file."), 1);
+    goto create_error;
+  }
+
+  cupsFileClose(fp);
+
+  return (pc);
+
+ /*
+  * If we get here the file was bad - free any data and return...
+  */
+
+  create_error:
+
+  cupsFileClose(fp);
+  _ppdCacheDestroy(pc);
+
+  return (NULL);
+}
+
+
+/*
+ * '_ppdCacheCreateWithPPD()' - Create PWG mapping data from a PPD file.
  */
 
-_pwg_t *                               /* O - PWG mapping data */
-_pwgCreateWithPPD(ppd_file_t *ppd)     /* I - PPD file */
+_ppd_cache_t *                         /* O - PPD cache and mapping data */
+_ppdCacheCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
 {
   int                  i, j, k;        /* Looping vars */
-  _pwg_t               *pwg;           /* PWG mapping data */
+  _ppd_cache_t         *pc;            /* PWG mapping data */
   ppd_option_t         *input_slot,    /* InputSlot option */
                        *media_type,    /* MediaType option */
                        *output_bin,    /* OutputBin option */
@@ -89,7 +497,8 @@ _pwgCreateWithPPD(ppd_file_t *ppd)   /* I - PPD file */
                                        /* Normalized PPD name */
   const char           *pwg_name;      /* Standard PWG media name */
   _pwg_media_t         *pwg_media;     /* PWG media data */
-  _pwg_output_mode_t   pwg_output_mode;/* output-mode index */
+  _pwg_print_color_mode_t pwg_print_color_mode;
+                                       /* print-color-mode index */
   _pwg_print_quality_t pwg_print_quality;
                                        /* print-quality index */
   int                  similar;        /* Are the old and new size similar? */
@@ -109,7 +518,7 @@ _pwgCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
   _pwg_size_t           *new_size;     /* New size to add, if any */
 
 
-  DEBUG_printf(("_pwgCreateWithPPD(ppd=%p)", ppd));
+  DEBUG_printf(("_ppdCacheCreateWithPPD(ppd=%p)", ppd));
 
  /*
   * Range check input...
@@ -122,9 +531,9 @@ _pwgCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
   * Allocate memory...
   */
 
-  if ((pwg = calloc(1, sizeof(_pwg_t))) == NULL)
+  if ((pc = calloc(1, sizeof(_ppd_cache_t))) == NULL)
   {
-    DEBUG_puts("_pwgCreateWithPPD: Unable to allocate _pwg_t.");
+    DEBUG_puts("_ppdCacheCreateWithPPD: Unable to allocate _ppd_cache_t.");
     goto create_error;
   }
 
@@ -134,18 +543,18 @@ _pwgCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
 
   if (ppd->num_sizes == 0)
   {
-    DEBUG_puts("_pwgCreateWithPPD: No page sizes in PPD.");
+    DEBUG_puts("_ppdCacheCreateWithPPD: No page sizes in PPD.");
     goto create_error;
   }
 
-  if ((pwg->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
+  if ((pc->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL)
   {
-    DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_size_t's.",
-                  ppd->num_sizes));
+    DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+                  "_pwg_size_t's.", ppd->num_sizes));
     goto create_error;
   }
 
-  for (i = ppd->num_sizes, pwg_size = pwg->sizes, ppd_size = ppd->sizes;
+  for (i = ppd->num_sizes, pwg_size = pc->sizes, ppd_size = ppd->sizes;
        i > 0;
        i --, ppd_size ++)
   {
@@ -166,8 +575,8 @@ _pwgCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
       * Standard name, do we have conflicts?
       */
 
-      for (j = 0; j < pwg->num_sizes; j ++)
-        if (!strcmp(pwg->sizes[j].map.pwg, pwg_media->pwg))
+      for (j = 0; j < pc->num_sizes; j ++)
+        if (!strcmp(pc->sizes[j].map.pwg, pwg_media->pwg))
        {
          pwg_media = NULL;
          break;
@@ -215,7 +624,7 @@ _pwgCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
     new_borderless = new_bottom == 0 && new_top == 0 &&
                      new_left == 0 && new_right == 0;
 
-    for (k = pwg->num_sizes, similar = 0, old_size = pwg->sizes, new_size = NULL;
+    for (k = pc->num_sizes, similar = 0, old_size = pc->sizes, new_size = NULL;
          k > 0 && !similar;
          k --, old_size ++)
     {
@@ -252,7 +661,7 @@ _pwgCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
       */
 
       new_size = pwg_size ++;
-      pwg->num_sizes ++;
+      pc->num_sizes ++;
     }
 
     if (new_size)
@@ -281,21 +690,21 @@ _pwgCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
     _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
                     _PWG_FROMPTS(ppd->custom_max[0]),
                     _PWG_FROMPTS(ppd->custom_max[1]));
-    pwg->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
-    pwg->custom_max_width   = _PWG_FROMPTS(ppd->custom_max[0]);
-    pwg->custom_max_length  = _PWG_FROMPTS(ppd->custom_max[1]);
+    pc->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
+    pc->custom_max_width   = _PWG_FROMPTS(ppd->custom_max[0]);
+    pc->custom_max_length  = _PWG_FROMPTS(ppd->custom_max[1]);
 
     _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
                     _PWG_FROMPTS(ppd->custom_min[0]),
                     _PWG_FROMPTS(ppd->custom_min[1]));
-    pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
-    pwg->custom_min_width   = _PWG_FROMPTS(ppd->custom_min[0]);
-    pwg->custom_min_length  = _PWG_FROMPTS(ppd->custom_min[1]);
-
-    pwg->custom_size.left   = _PWG_FROMPTS(ppd->custom_margins[0]);
-    pwg->custom_size.bottom = _PWG_FROMPTS(ppd->custom_margins[1]);
-    pwg->custom_size.right  = _PWG_FROMPTS(ppd->custom_margins[2]);
-    pwg->custom_size.top    = _PWG_FROMPTS(ppd->custom_margins[3]);
+    pc->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
+    pc->custom_min_width   = _PWG_FROMPTS(ppd->custom_min[0]);
+    pc->custom_min_length  = _PWG_FROMPTS(ppd->custom_min[1]);
+
+    pc->custom_size.left   = _PWG_FROMPTS(ppd->custom_margins[0]);
+    pc->custom_size.bottom = _PWG_FROMPTS(ppd->custom_margins[1]);
+    pc->custom_size.right  = _PWG_FROMPTS(ppd->custom_margins[2]);
+    pc->custom_size.top    = _PWG_FROMPTS(ppd->custom_margins[3]);
   }
 
  /*
@@ -307,20 +716,20 @@ _pwgCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
 
   if (input_slot)
   {
-    pwg->source_option = _cupsStrAlloc(input_slot->keyword);
+    pc->source_option = _cupsStrAlloc(input_slot->keyword);
 
-    if ((pwg->sources = calloc(input_slot->num_choices,
+    if ((pc->sources = calloc(input_slot->num_choices,
                                sizeof(_pwg_map_t))) == NULL)
     {
-      DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's "
-                    "for InputSlot.", input_slot->num_choices));
+      DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+                    "_pwg_map_t's for InputSlot.", input_slot->num_choices));
       goto create_error;
     }
 
-    pwg->num_sources = input_slot->num_choices;
+    pc->num_sources = input_slot->num_choices;
 
     for (i = input_slot->num_choices, choice = input_slot->choices,
-             map = pwg->sources;
+             map = pc->sources;
         i > 0;
         i --, choice ++, map ++)
     {
@@ -373,18 +782,18 @@ _pwgCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
 
   if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
   {
-    if ((pwg->types = calloc(media_type->num_choices,
+    if ((pc->types = calloc(media_type->num_choices,
                              sizeof(_pwg_map_t))) == NULL)
     {
-      DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's "
-                    "for MediaType.", media_type->num_choices));
+      DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+                    "_pwg_map_t's for MediaType.", media_type->num_choices));
       goto create_error;
     }
 
-    pwg->num_types = media_type->num_choices;
+    pc->num_types = media_type->num_choices;
 
     for (i = media_type->num_choices, choice = media_type->choices,
-             map = pwg->types;
+             map = pc->types;
         i > 0;
         i --, choice ++, map ++)
     {
@@ -436,18 +845,18 @@ _pwgCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
 
   if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL)
   {
-    if ((pwg->bins = calloc(output_bin->num_choices,
+    if ((pc->bins = calloc(output_bin->num_choices,
                              sizeof(_pwg_map_t))) == NULL)
     {
-      DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's "
-                    "for OutputBin.", output_bin->num_choices));
+      DEBUG_printf(("_ppdCacheCreateWithPPD: Unable to allocate %d "
+                    "_pwg_map_t's for OutputBin.", output_bin->num_choices));
       goto create_error;
     }
 
-    pwg->num_bins = output_bin->num_choices;
+    pc->num_bins = output_bin->num_choices;
 
     for (i = output_bin->num_choices, choice = output_bin->choices,
-             map = pwg->bins;
+             map = pc->bins;
         i > 0;
         i --, choice ++, map ++)
     {
@@ -526,28 +935,28 @@ _pwgCreateWithPPD(ppd_file_t *ppd)        /* I - PPD file */
         if (output_mode)
        {
          if (!strcmp(output_mode, "monochrome"))
-           pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+           pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
          else
-           pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+           pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
        }
        else if (color_model_val)
        {
          if (!strcasecmp(color_model_val, "Gray"))
-           pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+           pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
          else
-           pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+           pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
        }
        else
-         pwg_output_mode = _PWG_OUTPUT_MODE_COLOR;
+         pwg_print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
 
        /*
         * Save the options for this combination as needed...
        */
 
-        if (!pwg->num_presets[pwg_output_mode][pwg_print_quality])
-         pwg->num_presets[pwg_output_mode][pwg_print_quality] =
+        if (!pc->num_presets[pwg_print_color_mode][pwg_print_quality])
+         pc->num_presets[pwg_print_color_mode][pwg_print_quality] =
              _ppdParseOptions(ppd_attr->value, 0,
-                              pwg->presets[pwg_output_mode] +
+                              pc->presets[pwg_print_color_mode] +
                                   pwg_print_quality, _PPD_PARSE_OPTIONS);
       }
 
@@ -556,9 +965,9 @@ _pwgCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
     while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) != NULL);
   }
 
-  if (!pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] &&
-      !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] &&
-      !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH])
+  if (!pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] &&
+      !pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] &&
+      !pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH])
   {
    /*
     * Try adding some common color options to create grayscale presets.  These
@@ -612,20 +1021,20 @@ _pwgCreateWithPPD(ppd_file_t *ppd)       /* I - PPD file */
           pwg_print_quality < _PWG_PRINT_QUALITY_MAX;
           pwg_print_quality ++)
       {
-       if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_print_quality])
+       if (pc->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][pwg_print_quality])
        {
         /*
          * Copy the color options...
          */
 
-         num_options = pwg->num_presets[_PWG_OUTPUT_MODE_COLOR]
+         num_options = pc->num_presets[_PWG_PRINT_COLOR_MODE_COLOR]
                                        [pwg_print_quality];
          options     = calloc(sizeof(cups_option_t), num_options);
 
          if (options)
          {
            for (i = num_options, moption = options,
-                    coption = pwg->presets[_PWG_OUTPUT_MODE_COLOR]
+                    coption = pc->presets[_PWG_PRINT_COLOR_MODE_COLOR]
                                           [pwg_print_quality];
                 i > 0;
                 i --, moption ++, coption ++)
@@ -634,9 +1043,9 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
              moption->value = _cupsStrRetain(coption->value);
            }
 
-           pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+           pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][pwg_print_quality] =
                num_options;
-           pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+           pc->presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][pwg_print_quality] =
                options;
          }
        }
@@ -647,11 +1056,11 @@ _pwgCreateWithPPD(ppd_file_t *ppd)       /* I - PPD file */
        * Add the grayscale option to the preset...
        */
 
-       pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] =
+       pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME][pwg_print_quality] =
            cupsAddOption(color_option, gray_choice,
-                         pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME]
+                         pc->num_presets[_PWG_PRINT_COLOR_MODE_MONOCHROME]
                                          [pwg_print_quality],
-                         pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME] +
+                         pc->presets[_PWG_PRINT_COLOR_MODE_MONOCHROME] +
                              pwg_print_quality);
       }
     }
@@ -669,28 +1078,28 @@ _pwgCreateWithPPD(ppd_file_t *ppd)       /* I - PPD file */
 
   if (duplex)
   {
-    pwg->sides_option = _cupsStrAlloc(duplex->keyword);
+    pc->sides_option = _cupsStrAlloc(duplex->keyword);
 
     for (i = duplex->num_choices, choice = duplex->choices;
          i > 0;
         i --, choice ++)
     {
       if ((!strcasecmp(choice->choice, "None") ||
-          !strcasecmp(choice->choice, "False")) && !pwg->sides_1sided)
-        pwg->sides_1sided = _cupsStrAlloc(choice->choice);
+          !strcasecmp(choice->choice, "False")) && !pc->sides_1sided)
+        pc->sides_1sided = _cupsStrAlloc(choice->choice);
       else if ((!strcasecmp(choice->choice, "DuplexNoTumble") ||
                !strcasecmp(choice->choice, "LongEdge") ||
-               !strcasecmp(choice->choice, "Top")) && !pwg->sides_2sided_long)
-        pwg->sides_2sided_long = _cupsStrAlloc(choice->choice);
+               !strcasecmp(choice->choice, "Top")) && !pc->sides_2sided_long)
+        pc->sides_2sided_long = _cupsStrAlloc(choice->choice);
       else if ((!strcasecmp(choice->choice, "DuplexTumble") ||
                !strcasecmp(choice->choice, "ShortEdge") ||
                !strcasecmp(choice->choice, "Bottom")) &&
-              !pwg->sides_2sided_short)
-        pwg->sides_2sided_short = _cupsStrAlloc(choice->choice);
+              !pc->sides_2sided_short)
+        pc->sides_2sided_short = _cupsStrAlloc(choice->choice);
     }
   }
 
-  return (pwg);
+  return (pc);
 
  /*
   * If we get here we need to destroy the PWG mapping data and return NULL...
@@ -699,20 +1108,101 @@ _pwgCreateWithPPD(ppd_file_t *ppd)      /* I - PPD file */
   create_error:
 
   _cupsSetError(IPP_INTERNAL_ERROR, _("Out of memory."), 1);
-  _pwgDestroy(pwg);
+  _ppdCacheDestroy(pc);
 
   return (NULL);
 }
 
 
 /*
- * '_pwgGetBin()' - Get the PWG output-bin keyword associated with a PPD
+ * '_ppdCacheDestroy()' - Free all memory used for PWG mapping data.
+ */
+
+void
+_ppdCacheDestroy(_ppd_cache_t *pc)     /* I - PPD cache and mapping data */
+{
+  int          i;                      /* Looping var */
+  _pwg_map_t   *map;                   /* Current map */
+  _pwg_size_t  *size;                  /* Current size */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!pc)
+    return;
+
+ /*
+  * Free memory as needed...
+  */
+
+  if (pc->bins)
+  {
+    for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++)
+    {
+      _cupsStrFree(map->pwg);
+      _cupsStrFree(map->ppd);
+    }
+
+    free(pc->bins);
+  }
+
+  if (pc->sizes)
+  {
+    for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
+    {
+      _cupsStrFree(size->map.pwg);
+      _cupsStrFree(size->map.ppd);
+    }
+
+    free(pc->sizes);
+  }
+
+  if (pc->source_option)
+    _cupsStrFree(pc->source_option);
+
+  if (pc->sources)
+  {
+    for (i = pc->num_sources, map = pc->sources; i > 0; i --, map ++)
+    {
+      _cupsStrFree(map->pwg);
+      _cupsStrFree(map->ppd);
+    }
+
+    free(pc->sources);
+  }
+
+  if (pc->types)
+  {
+    for (i = pc->num_types, map = pc->types; i > 0; i --, map ++)
+    {
+      _cupsStrFree(map->pwg);
+      _cupsStrFree(map->ppd);
+    }
+
+    free(pc->types);
+  }
+
+  if (pc->custom_max_keyword)
+    _cupsStrFree(pc->custom_max_keyword);
+
+  if (pc->custom_min_keyword)
+    _cupsStrFree(pc->custom_min_keyword);
+
+  free(pc);
+}
+
+
+/*
+ * '_ppdCacheGetBin()' - Get the PWG output-bin keyword associated with a PPD
  *                  OutputBin.
  */
 
 const char *                           /* O - output-bin or NULL */
-_pwgGetBin(_pwg_t     *pwg,            /* I - PWG mapping data */
-          const char *output_bin)      /* I - PPD OutputBin string */
+_ppdCacheGetBin(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    const char   *output_bin)          /* I - PPD OutputBin string */
 {
   int  i;                              /* Looping var */
 
@@ -721,7 +1211,7 @@ _pwgGetBin(_pwg_t     *pwg,                /* I - PWG mapping data */
   * Range check input...
   */
 
-  if (!pwg || !output_bin)
+  if (!pc || !output_bin)
     return (NULL);
 
  /*
@@ -729,29 +1219,30 @@ _pwgGetBin(_pwg_t     *pwg,              /* I - PWG mapping data */
   */
 
 
-  for (i = 0; i < pwg->num_bins; i ++)
-    if (!strcasecmp(output_bin, pwg->bins[i].ppd))
-      return (pwg->bins[i].pwg);
+  for (i = 0; i < pc->num_bins; i ++)
+    if (!strcasecmp(output_bin, pc->bins[i].ppd))
+      return (pc->bins[i].pwg);
 
   return (NULL);
 }
 
 
 /*
- * '_pwgGetInputSlot()' - Get the PPD InputSlot associated with the job
+ * '_ppdCacheGetInputSlot()' - Get the PPD InputSlot associated with the job
  *                        attributes or a keyword string.
  */
 
 const char *                           /* O - PPD InputSlot or NULL */
-_pwgGetInputSlot(_pwg_t     *pwg,      /* I - PWG mapping data */
-                 ipp_t      *job,      /* I - Job attributes or NULL */
-                const char *keyword)   /* I - Keyword string or NULL */
+_ppdCacheGetInputSlot(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    ipp_t        *job,                 /* I - Job attributes or NULL */
+    const char   *keyword)             /* I - Keyword string or NULL */
 {
  /*
   * Range check input...
   */
 
-  if (!pwg || pwg->num_sources == 0 || (!job && !keyword))
+  if (!pc || pc->num_sources == 0 || (!job && !keyword))
     return (NULL);
 
   if (job && !keyword)
@@ -792,9 +1283,9 @@ _pwgGetInputSlot(_pwg_t     *pwg,  /* I - PWG mapping data */
   {
     int        i;                              /* Looping var */
 
-    for (i = 0; i < pwg->num_sources; i ++)
-      if (!strcasecmp(keyword, pwg->sources[i].pwg))
-        return (pwg->sources[i].ppd);
+    for (i = 0; i < pc->num_sources; i ++)
+      if (!strcasecmp(keyword, pc->sources[i].pwg))
+        return (pc->sources[i].ppd);
   }
 
   return (NULL);
@@ -802,20 +1293,21 @@ _pwgGetInputSlot(_pwg_t     *pwg,        /* I - PWG mapping data */
 
 
 /*
- * '_pwgGetMediaType()' - Get the PPD MediaType associated with the job
+ * '_ppdCacheGetMediaType()' - Get the PPD MediaType associated with the job
  *                        attributes or a keyword string.
  */
 
 const char *                           /* O - PPD MediaType or NULL */
-_pwgGetMediaType(_pwg_t     *pwg,      /* I - PWG mapping data */
-                 ipp_t      *job,      /* I - Job attributes or NULL */
-                const char *keyword)   /* I - Keyword string or NULL */
+_ppdCacheGetMediaType(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    ipp_t        *job,                 /* I - Job attributes or NULL */
+    const char   *keyword)             /* I - Keyword string or NULL */
 {
  /*
   * Range check input...
   */
 
-  if (!pwg || pwg->num_types == 0 || (!job && !keyword))
+  if (!pc || pc->num_types == 0 || (!job && !keyword))
     return (NULL);
 
   if (job && !keyword)
@@ -845,9 +1337,9 @@ _pwgGetMediaType(_pwg_t     *pwg,  /* I - PWG mapping data */
   {
     int        i;                              /* Looping var */
 
-    for (i = 0; i < pwg->num_types; i ++)
-      if (!strcasecmp(keyword, pwg->types[i].pwg))
-        return (pwg->types[i].ppd);
+    for (i = 0; i < pc->num_types; i ++)
+      if (!strcasecmp(keyword, pc->types[i].pwg))
+        return (pc->types[i].ppd);
   }
 
   return (NULL);
@@ -855,13 +1347,14 @@ _pwgGetMediaType(_pwg_t     *pwg,        /* I - PWG mapping data */
 
 
 /*
- * '_pwgGetOutputBin()' - Get the PPD OutputBin associated with the keyword
+ * '_ppdCacheGetOutputBin()' - Get the PPD OutputBin associated with the keyword
  *                        string.
  */
 
 const char *                           /* O - PPD OutputBin or NULL */
-_pwgGetOutputBin(_pwg_t     *pwg,      /* I - PWG mapping data */
-                const char *output_bin)/* I - Keyword string */
+_ppdCacheGetOutputBin(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    const char   *output_bin)          /* I - Keyword string */
 {
   int  i;                              /* Looping var */
 
@@ -870,7 +1363,7 @@ _pwgGetOutputBin(_pwg_t     *pwg,  /* I - PWG mapping data */
   * Range check input...
   */
 
-  if (!pwg || !output_bin)
+  if (!pc || !output_bin)
     return (NULL);
 
  /*
@@ -878,24 +1371,25 @@ _pwgGetOutputBin(_pwg_t     *pwg,        /* I - PWG mapping data */
   */
 
 
-  for (i = 0; i < pwg->num_bins; i ++)
-    if (!strcasecmp(output_bin, pwg->bins[i].pwg))
-      return (pwg->bins[i].ppd);
+  for (i = 0; i < pc->num_bins; i ++)
+    if (!strcasecmp(output_bin, pc->bins[i].pwg))
+      return (pc->bins[i].ppd);
 
   return (NULL);
 }
 
 
 /*
- * '_pwgGetPageSize()' - Get the PPD PageSize associated with the job
+ * '_ppdCacheGetPageSize()' - Get the PPD PageSize associated with the job
  *                       attributes or a keyword string.
  */
 
 const char *                           /* O - PPD PageSize or NULL */
-_pwgGetPageSize(_pwg_t     *pwg,       /* I - PWG mapping data */
-                ipp_t      *job,       /* I - Job attributes or NULL */
-               const char *keyword,    /* I - Keyword string or NULL */
-               int        *exact)      /* O - 1 if exact match, 0 otherwise */
+_ppdCacheGetPageSize(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    ipp_t        *job,                 /* I - Job attributes or NULL */
+    const char   *keyword,             /* I - Keyword string or NULL */
+    int          *exact)               /* O - 1 if exact match, 0 otherwise */
 {
   int          i;                      /* Looping var */
   _pwg_size_t  *size,                  /* Current size */
@@ -913,14 +1407,14 @@ _pwgGetPageSize(_pwg_t     *pwg, /* I - PWG mapping data */
   const char   *ppd_name;              /* PPD media name */
 
 
-  DEBUG_printf(("_pwgGetPageSize(pwg=%p, job=%p, keyword=\"%s\", exact=%p)",
-               pwg, job, keyword, exact));
+  DEBUG_printf(("_ppdCacheGetPageSize(pc=%p, job=%p, keyword=\"%s\", exact=%p)",
+               pc, job, keyword, exact));
 
  /*
   * Range check input...
   */
 
-  if (!pwg || (!job && !keyword))
+  if (!pc || (!job && !keyword))
     return (NULL);
 
   if (exact)
@@ -942,10 +1436,10 @@ _pwgGetPageSize(_pwg_t     *pwg, /* I - PWG mapping data */
 
 #ifdef DEBUG
     if (attr)
-      DEBUG_printf(("1_pwgGetPageSize: Found attribute %s (%s)", attr->name,
-                   ippTagString(attr->value_tag)));
+      DEBUG_printf(("1_ppdCacheGetPageSize: Found attribute %s (%s)",
+                    attr->name, ippTagString(attr->value_tag)));
     else
-      DEBUG_puts("1_pwgGetPageSize: Did not find media attribute.");
+      DEBUG_puts("1_ppdCacheGetPageSize: Did not find media attribute.");
 #endif /* DEBUG */
 
     if (attr && (attr->value_tag == IPP_TAG_NAME ||
@@ -953,7 +1447,7 @@ _pwgGetPageSize(_pwg_t     *pwg,   /* I - PWG mapping data */
       ppd_name = attr->values[0].string.text;
   }
 
-  DEBUG_printf(("1_pwgGetPageSize: ppd_name=\"%s\"", ppd_name));
+  DEBUG_printf(("1_ppdCacheGetPageSize: ppd_name=\"%s\"", ppd_name));
 
   if (ppd_name)
   {
@@ -961,10 +1455,10 @@ _pwgGetPageSize(_pwg_t     *pwg, /* I - PWG mapping data */
     * Try looking up the named PPD size first...
     */
 
-    for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
+    for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
     {
-      DEBUG_printf(("2_pwgGetPageSize: size[%d]=[\"%s\" \"%s\"]",
-                    (int)(size - pwg->sizes), size->map.pwg, size->map.ppd));
+      DEBUG_printf(("2_ppdCacheGetPageSize: size[%d]=[\"%s\" \"%s\"]",
+                    (int)(size - pc->sizes), size->map.pwg, size->map.ppd));
 
       if (!strcasecmp(ppd_name, size->map.ppd) ||
           !strcasecmp(ppd_name, size->map.pwg))
@@ -972,7 +1466,7 @@ _pwgGetPageSize(_pwg_t     *pwg,   /* I - PWG mapping data */
        if (exact)
          *exact = 1;
 
-        DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\"", ppd_name));
+        DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\"", ppd_name));
 
         return (size->map.ppd);
       }
@@ -1019,7 +1513,7 @@ _pwgGetPageSize(_pwg_t     *pwg,  /* I - PWG mapping data */
   if (!ppd_name || strncasecmp(ppd_name, "Custom.", 7) ||
       strncasecmp(ppd_name, "custom_", 7))
   {
-    for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
+    for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
     {
      /*
       * Adobe uses a size matching algorithm with an epsilon of 5 points, which
@@ -1065,7 +1559,7 @@ _pwgGetPageSize(_pwg_t     *pwg,  /* I - PWG mapping data */
       if (exact)
        *exact = 1;
 
-      DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\"", size->map.ppd));
+      DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\"", size->map.ppd));
 
       return (size->map.ppd);
     }
@@ -1073,7 +1567,7 @@ _pwgGetPageSize(_pwg_t     *pwg,  /* I - PWG mapping data */
 
   if (closest)
   {
-    DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\" (closest)",
+    DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\" (closest)",
                   closest->map.ppd));
 
     return (closest->map.ppd);
@@ -1083,24 +1577,24 @@ _pwgGetPageSize(_pwg_t     *pwg,        /* I - PWG mapping data */
   * If we get here we need to check for custom page size support...
   */
 
-  if (jobsize.width >= pwg->custom_min_width &&
-      jobsize.width <= pwg->custom_max_width &&
-      jobsize.length >= pwg->custom_min_length &&
-      jobsize.length <= pwg->custom_max_length)
+  if (jobsize.width >= pc->custom_min_width &&
+      jobsize.width <= pc->custom_max_width &&
+      jobsize.length >= pc->custom_min_length &&
+      jobsize.length <= pc->custom_max_length)
   {
    /*
     * In range, format as Custom.WWWWxLLLL (points).
     */
 
-    snprintf(pwg->custom_ppd_size, sizeof(pwg->custom_ppd_size), "Custom.%dx%d",
+    snprintf(pc->custom_ppd_size, sizeof(pc->custom_ppd_size), "Custom.%dx%d",
              (int)_PWG_TOPTS(jobsize.width), (int)_PWG_TOPTS(jobsize.length));
 
     if (margins_set && exact)
     {
-      dleft   = pwg->custom_size.left - jobsize.left;
-      dright  = pwg->custom_size.right - jobsize.right;
-      dtop    = pwg->custom_size.top - jobsize.top;
-      dbottom = pwg->custom_size.bottom - jobsize.bottom;
+      dleft   = pc->custom_size.left - jobsize.left;
+      dright  = pc->custom_size.right - jobsize.right;
+      dtop    = pc->custom_size.top - jobsize.top;
+      dbottom = pc->custom_size.bottom - jobsize.bottom;
 
       if (dleft > -35 && dleft < 35 && dright > -35 && dright < 35 &&
           dtop > -35 && dtop < 35 && dbottom > -35 && dbottom < 35)
@@ -1109,29 +1603,30 @@ _pwgGetPageSize(_pwg_t     *pwg,        /* I - PWG mapping data */
     else if (exact)
       *exact = 1;
 
-    DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\" (custom)",
-                  pwg->custom_ppd_size));
+    DEBUG_printf(("1_ppdCacheGetPageSize: Returning \"%s\" (custom)",
+                  pc->custom_ppd_size));
 
-    return (pwg->custom_ppd_size);
+    return (pc->custom_ppd_size);
   }
 
  /*
   * No custom page size support or the size is out of range - return NULL.
   */
 
-  DEBUG_puts("1_pwgGetPageSize: Returning NULL");
+  DEBUG_puts("1_ppdCacheGetPageSize: Returning NULL");
 
   return (NULL);
 }
 
 
 /*
- * '_pwgGetSize()' - Get the PWG size associated with a PPD PageSize.
+ * '_ppdCacheGetSize()' - Get the PWG size associated with a PPD PageSize.
  */
 
 _pwg_size_t *                          /* O - PWG size or NULL */
-_pwgGetSize(_pwg_t     *pwg,           /* I - PWG mapping data */
-            const char *page_size)     /* I - PPD PageSize */
+_ppdCacheGetSize(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    const char   *page_size)           /* I - PPD PageSize */
 {
   int          i;
   _pwg_size_t  *size;                  /* Current size */
@@ -1141,7 +1636,7 @@ _pwgGetSize(_pwg_t     *pwg,              /* I - PWG mapping data */
   * Range check input...
   */
 
-  if (!pwg || !page_size)
+  if (!pc || !page_size)
     return (NULL);
 
   if (!strncasecmp(page_size, "Custom.", 7))
@@ -1201,17 +1696,17 @@ _pwgGetSize(_pwg_t     *pwg,            /* I - PWG mapping data */
       l *= 2540.0 / 72.0;
     }
 
-    pwg->custom_size.width  = (int)w;
-    pwg->custom_size.length = (int)l;
+    pc->custom_size.width  = (int)w;
+    pc->custom_size.length = (int)l;
 
-    return (&(pwg->custom_size));
+    return (&(pc->custom_size));
   }
 
  /*
   * Not a custom size - look it up...
   */
 
-  for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
+  for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
     if (!strcasecmp(page_size, size->map.ppd))
       return (size);
 
@@ -1220,12 +1715,14 @@ _pwgGetSize(_pwg_t     *pwg,            /* I - PWG mapping data */
 
 
 /*
- * '_pwgGetSource()' - Get the PWG media-source associated with a PPD InputSlot.
+ * '_ppdCacheGetSource()' - Get the PWG media-source associated with a PPD
+ *                          InputSlot.
  */
 
 const char *                           /* O - PWG media-source keyword */
-_pwgGetSource(_pwg_t     *pwg,         /* I - PWG mapping data */
-              const char *input_slot)  /* I - PPD InputSlot */
+_ppdCacheGetSource(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    const char   *input_slot)          /* I - PPD InputSlot */
 {
   int          i;                      /* Looping var */
   _pwg_map_t   *source;                /* Current source */
@@ -1235,10 +1732,10 @@ _pwgGetSource(_pwg_t     *pwg,          /* I - PWG mapping data */
   * Range check input...
   */
 
-  if (!pwg || !input_slot)
+  if (!pc || !input_slot)
     return (NULL);
 
-  for (i = pwg->num_sources, source = pwg->sources; i > 0; i --, source ++)
+  for (i = pc->num_sources, source = pc->sources; i > 0; i --, source ++)
     if (!strcasecmp(input_slot, source->ppd))
       return (source->pwg);
 
@@ -1247,12 +1744,14 @@ _pwgGetSource(_pwg_t     *pwg,          /* I - PWG mapping data */
 
 
 /*
- * '_pwgGetType()' - Get the PWG media-type associated with a PPD MediaType.
+ * '_ppdCacheGetType()' - Get the PWG media-type associated with a PPD
+ *                        MediaType.
  */
 
 const char *                           /* O - PWG media-type keyword */
-_pwgGetType(_pwg_t     *pwg,           /* I - PWG mapping data */
-           const char *media_type)     /* I - PPD MediaType */
+_ppdCacheGetType(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    const char   *media_type)          /* I - PPD MediaType */
 {
   int          i;                      /* Looping var */
   _pwg_map_t   *type;                  /* Current type */
@@ -1262,10 +1761,10 @@ _pwgGetType(_pwg_t     *pwg,            /* I - PWG mapping data */
   * Range check input...
   */
 
-  if (!pwg || !media_type)
+  if (!pc || !media_type)
     return (NULL);
 
-  for (i = pwg->num_types, type = pwg->types; i > 0; i --, type ++)
+  for (i = pc->num_types, type = pc->types; i > 0; i --, type ++)
     if (!strcasecmp(media_type, type->ppd))
       return (type->pwg);
 
@@ -1274,7 +1773,142 @@ _pwgGetType(_pwg_t     *pwg,            /* I - PWG mapping data */
 
 
 /*
- * '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG source.
+ * '_ppdCacheWriteFile()' - Write PWG mapping data to a file.
+ */
+
+int                                    /* O - 1 on success, 0 on failure */
+_ppdCacheWriteFile(
+    _ppd_cache_t *pc,                  /* I - PPD cache and mapping data */
+    const char   *filename)            /* I - File to write */
+{
+  int          i, j, k;                /* Looping vars */
+  cups_file_t  *fp;                    /* Output file */
+  _pwg_size_t  *size;                  /* Current size */
+  _pwg_map_t   *map;                   /* Current map */
+  cups_option_t        *option;                /* Current option */
+
+
+ /*
+  * Range check input...
+  */
+
+  if (!pc || !filename)
+  {
+    _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
+    return (0);
+  }
+
+ /*
+  * Open the file and write with compression...
+  */
+
+  if ((fp = cupsFileOpen(filename, "w9")) == NULL)
+  {
+    _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
+    return (0);
+  }
+
+ /*
+  * Standard header...
+  */
+
+  cupsFilePuts(fp, "#CUPS-PWGPPD\n");
+
+ /*
+  * Output bins...
+  */
+
+  if (pc->num_bins > 0)
+  {
+    cupsFilePrintf(fp, "NumBins %d\n", pc->num_bins);
+    for (i = pc->num_bins, map = pc->bins; i > 0; i --, map ++)
+      cupsFilePrintf(fp, "Bin %s %s\n", map->pwg, map->ppd);
+  }
+
+ /*
+  * Media sizes...
+  */
+
+  cupsFilePrintf(fp, "NumSizes %d\n", pc->num_sizes);
+  for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
+    cupsFilePrintf(fp, "Size %s %s %d %d %d %d %d %d\n", size->map.pwg,
+                  size->map.ppd, size->width, size->length, size->left,
+                  size->bottom, size->right, size->top);
+  if (pc->custom_max_width > 0)
+    cupsFilePrintf(fp, "CustomSize %d %d %d %d %d %d %d %d\n",
+                   pc->custom_max_width, pc->custom_max_length,
+                  pc->custom_min_width, pc->custom_min_length,
+                  pc->custom_size.left, pc->custom_size.bottom,
+                  pc->custom_size.right, pc->custom_size.top);
+
+ /*
+  * Media sources...
+  */
+
+  if (pc->source_option)
+    cupsFilePrintf(fp, "SourceOption %s\n", pc->source_option);
+
+  if (pc->num_sources > 0)
+  {
+    cupsFilePrintf(fp, "NumSources %d\n", pc->num_sources);
+    for (i = pc->num_sources, map = pc->sources; i > 0; i --, map ++)
+      cupsFilePrintf(fp, "Source %s %s\n", map->pwg, map->ppd);
+  }
+
+ /*
+  * Media types...
+  */
+
+  if (pc->num_types > 0)
+  {
+    cupsFilePrintf(fp, "NumTypes %d\n", pc->num_types);
+    for (i = pc->num_types, map = pc->types; i > 0; i --, map ++)
+      cupsFilePrintf(fp, "Type %s %s\n", map->pwg, map->ppd);
+  }
+
+ /*
+  * Presets...
+  */
+
+  for (i = _PWG_PRINT_COLOR_MODE_MONOCHROME; i < _PWG_PRINT_COLOR_MODE_MAX; i ++)
+    for (j = _PWG_PRINT_QUALITY_DRAFT; j < _PWG_PRINT_QUALITY_MAX; j ++)
+      if (pc->num_presets[i][j])
+      {
+       cupsFilePrintf(fp, "Preset %d %d", i, j);
+       for (k = pc->num_presets[i][j], option = pc->presets[i][j];
+            k > 0;
+            k --, option ++)
+         cupsFilePrintf(fp, " %s=%s", option->name, option->value);
+       cupsFilePutChar(fp, '\n');
+      }
+
+ /*
+  * Duplex/sides...
+  */
+
+  if (pc->sides_option)
+    cupsFilePrintf(fp, "SidesOption %s\n", pc->sides_option);
+
+  if (pc->sides_1sided)
+    cupsFilePrintf(fp, "Sides1Sided %s\n", pc->sides_1sided);
+
+  if (pc->sides_2sided_long)
+    cupsFilePrintf(fp, "Sides2SidedLong %s\n", pc->sides_2sided_long);
+
+  if (pc->sides_2sided_short)
+    cupsFilePrintf(fp, "Sides2SidedShort %s\n", pc->sides_2sided_short);
+
+ /*
+  * Close and return...
+  */
+
+  return (!cupsFileClose(fp));
+}
+
+
+/*
+ * '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG
+ *                              media-source.
  */
 
 const char *                           /* O - InputSlot name */
@@ -1320,12 +1954,13 @@ _pwgInputSlotForSource(
 
 
 /*
- * '_pwgMediaTypeForType()' - Get the MediaType name for the given PWG type.
+ * '_pwgMediaTypeForType()' - Get the MediaType name for the given PWG
+ *                            media-type.
  */
 
 const char *                           /* O - MediaType name */
 _pwgMediaTypeForType(
-    const char *media_type,            /* I - PWG media-source */
+    const char *media_type,            /* I - PWG media-type */
     char       *name,                  /* I - Name buffer */
     size_t     namesize)               /* I - Size of name buffer */
 {
index d44c1ca0403b10f2821eb9b71ae60ede3b693d4d..de4d3dd79a9b1ebfef758d1eabedc1c6e0504252 100644 (file)
@@ -45,6 +45,13 @@ extern "C" {
 #  endif /* __cplusplus */
 
 
+/*
+ * Constants...
+ */
+
+#  define PPD_CACHE_VERSION    1       /* Version number in cache file */
+
+
 /*
  * Types and structures...
  */
@@ -71,12 +78,13 @@ typedef struct _ppd_cups_uiconsts_s /**** cupsUIConstraints ****/
   _ppd_cups_uiconst_t *constraints;    /* Constraints */
 } _ppd_cups_uiconsts_t;
 
-typedef enum _pwg_output_mode_e                /**** PWG output-mode indices ****/
+typedef enum _pwg_print_color_mode_e   /**** PWG print-color-mode indices ****/
 {
-  _PWG_OUTPUT_MODE_MONOCHROME = 0,     /* output-mode=monochrome */
-  _PWG_OUTPUT_MODE_COLOR,              /* output-mode=color */
-  _PWG_OUTPUT_MODE_MAX
-} _pwg_output_mode_t;
+  _PWG_PRINT_COLOR_MODE_MONOCHROME = 0,        /* print-color-mode=monochrome */
+  _PWG_PRINT_COLOR_MODE_COLOR,         /* print-color-mode=color */
+  /* Other proposed values are not supported by CUPS yet. */
+  _PWG_PRINT_COLOR_MODE_MAX
+} _pwg_print_color_mode_t;
 
 typedef enum _pwg_print_quality_e      /**** PWG print-quality indices ****/
 {
@@ -86,7 +94,7 @@ typedef enum _pwg_print_quality_e     /**** PWG print-quality indices ****/
   _PWG_PRINT_QUALITY_MAX
 } _pwg_print_quality_t;
 
-typedef struct _pwg_s                  /**** PWG-PPD conversion data ****/
+struct _ppd_cache_s                    /**** PPD cache and PWG conversion data ****/
 {
   int          num_bins;               /* Number of output bins */
   _pwg_map_t   *bins;                  /* Output bins */
@@ -105,21 +113,46 @@ typedef struct _pwg_s                     /**** PWG-PPD conversion data ****/
   _pwg_map_t   *sources;               /* Media sources */
   int          num_types;              /* Number of media types */
   _pwg_map_t   *types;                 /* Media types */
-  int          num_presets[_PWG_OUTPUT_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
-                                       /* Number of output-mode/print-quality options */
-  cups_option_t        *presets[_PWG_OUTPUT_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
-                                       /* output-mode/print-quality options */
+  int          num_presets[_PWG_PRINT_COLOR_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
+                                       /* Number of print-color-mode/print-quality options */
+  cups_option_t        *presets[_PWG_PRINT_COLOR_MODE_MAX][_PWG_PRINT_QUALITY_MAX];
+                                       /* print-color-mode/print-quality options */
   char         *sides_option,          /* PPD option for sides */
                *sides_1sided,          /* Choice for one-sided */
                *sides_2sided_long,     /* Choice for two-sided-long-edge */
                *sides_2sided_short;    /* Choice for two-sided-short-edge */
-} _pwg_t;
+  char         *product;               /* Product value */
+  cups_array_t *filters,               /* cupsFilter/cupsFilter2 values */
+               *prefilters;            /* cupsPreFilter values */
+  ipp_t                *attrs;                 /* Printer description attributes, if any */
+};
 
 
 /*
  * Prototypes...
  */
 
+extern _ppd_cache_t    *_ppdCacheCreateWithFile(const char *filename);
+extern _ppd_cache_t    *_ppdCacheCreateWithPPD(ppd_file_t *ppd);
+extern void            _ppdCacheDestroy(_ppd_cache_t *pc);
+extern const char      *_ppdCacheGetBin(_ppd_cache_t *pc,
+                                        const char *output_bin);
+extern const char      *_ppdCacheGetInputSlot(_ppd_cache_t *pc, ipp_t *job,
+                                              const char *keyword);
+extern const char      *_ppdCacheGetMediaType(_ppd_cache_t *pc, ipp_t *job,
+                                              const char *keyword);
+extern const char      *_ppdCacheGetOutputBin(_ppd_cache_t *pc,
+                                              const char *keyword);
+extern const char      *_ppdCacheGetPageSize(_ppd_cache_t *pc, ipp_t *job,
+                                             const char *keyword, int *exact);
+extern _pwg_size_t     *_ppdCacheGetSize(_ppd_cache_t *pc,
+                                         const char *page_size);
+extern const char      *_ppdCacheGetSource(_ppd_cache_t *pc,
+                                           const char *input_slot);
+extern const char      *_ppdCacheGetType(_ppd_cache_t *pc,
+                                         const char *media_type);
+extern int             _ppdCacheWriteFile(_ppd_cache_t *pc,
+                                          const char *filename);
 extern void            _ppdFreeLanguages(cups_array_t *languages);
 extern cups_encoding_t _ppdGetEncoding(const char *name);
 extern cups_array_t    *_ppdGetLanguages(ppd_file_t *ppd);
@@ -132,27 +165,12 @@ extern char               *_ppdNormalizeMakeAndModel(const char *make_and_model,
 extern int             _ppdParseOptions(const char *s, int num_options,
                                         cups_option_t **options,
                                         _ppd_parse_t which);
-extern _pwg_t          *_pwgCreateWithFile(const char *filename);
-extern _pwg_t          *_pwgCreateWithPPD(ppd_file_t *ppd);
-extern void            _pwgDestroy(_pwg_t *pwg);
-extern const char      *_pwgGetBin(_pwg_t *pwg, const char *output_bin);
-extern const char      *_pwgGetInputSlot(_pwg_t *pwg, ipp_t *job,
-                                         const char *keyword);
-extern const char      *_pwgGetMediaType(_pwg_t *pwg, ipp_t *job,
-                                         const char *keyword);
-extern const char      *_pwgGetOutputBin(_pwg_t *pwg, const char *keyword);
-extern const char      *_pwgGetPageSize(_pwg_t *pwg, ipp_t *job,
-                                        const char *keyword, int *exact);
-extern _pwg_size_t     *_pwgGetSize(_pwg_t *pwg, const char *page_size);
-extern const char      *_pwgGetSource(_pwg_t *pwg, const char *input_slot);
-extern const char      *_pwgGetType(_pwg_t *pwg, const char *media_type);
 extern const char      *_pwgInputSlotForSource(const char *media_source,
                                                char *name, size_t namesize);
 extern const char      *_pwgMediaTypeForType(const char *media_type,
-                                             char *name, size_t namesize);
+                                             char *name, size_t namesize);
 extern const char      *_pwgPageSizeForMedia(_pwg_media_t *media,
                                              char *name, size_t namesize);
-extern int             _pwgWriteFile(_pwg_t *pwg, const char *filename);
 
 
 /*
index e23615300c48aefea8ef9a895b66935bc41eec80..1b4c0b5cd7ca29f42d74e23fd02c39f18048aff5 100644 (file)
@@ -310,11 +310,11 @@ ppdClose(ppd_file_t *ppd)         /* I - PPD file record */
   }
 
  /*
-  * Free any PWG mapping data...
+  * Free any PPD cache/mapping data...
   */
 
-  if (ppd->pwg)
-    _pwgDestroy((_pwg_t *)ppd->pwg);
+  if (ppd->cache)
+    _ppdCacheDestroy(ppd->cache);
 
  /*
   * Free the whole record...
index af76a72cbfe3c30df8ad199866e3ba592db12f30..32a2f1e4eb67ea1a9a4f6137dc66d14ff32e6528 100644 (file)
@@ -273,6 +273,9 @@ typedef struct ppd_coption_s                /**** Custom Option @since CUPS 1.2/Mac OS X 10.5@
   cups_array_t *params;                /* Parameters */
 } ppd_coption_t;
 
+typedef struct _ppd_cache_s _ppd_cache_t;
+                                       /**** PPD cache and mapping data @since CUPS 1.5@ @private@ ****/
+
 typedef struct ppd_file_s              /**** PPD File ****/
 {
   int          language_level;         /* Language level of device */
@@ -337,7 +340,7 @@ typedef struct ppd_file_s           /**** PPD File ****/
   cups_array_t *cups_uiconstraints;    /* cupsUIConstraints @since CUPS 1.4/Mac OS X 10.6@ @private@ */
 
   /**** New in CUPS 1.5 ****/
-  void         *pwg;                   /* PWG to/from PPD mappings @since CUPS 1.5@ @private@ */
+  _ppd_cache_t *cache;                 /* PPD cache and mapping data @since CUPS 1.5@ @private@ */
 } ppd_file_t;
 
 
diff --git a/cups/pwg-file.c b/cups/pwg-file.c
deleted file mode 100644 (file)
index 52bac4d..0000000
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * "$Id$"
- *
- *   PWG load/save API implementation for CUPS.
- *
- *   Copyright 2010 by Apple Inc.
- *
- *   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/".
- *
- *   This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- *   _pwgCreateWithFile() - Create PWG mapping data from a written file.
- *   _pwgDestroy()        - Free all memory used for PWG mapping data.
- *   _pwgWriteFile()      - Write PWG mapping data to a file.
- */
-
-/*
- * Include necessary headers...
- */
-
-#include "cups-private.h"
-#include <math.h>
-
-
-/*
- * '_pwgCreateWithFile()' - Create PWG mapping data from a written file.
- *
- * Use the @link _pwgWriteFile@ function to write PWG mapping data to a file.
- */
-
-_pwg_t *                               /* O - PWG mapping data */
-_pwgCreateWithFile(const char *filename)/* I - File to read */
-{
-  cups_file_t  *fp;                    /* File */
-  _pwg_t       *pwg;                   /* PWG mapping data */
-  _pwg_size_t  *size;                  /* Current size */
-  _pwg_map_t   *map;                   /* Current map */
-  int          linenum,                /* Current line number */
-               num_bins,               /* Number of bins in file */
-               num_sizes,              /* Number of sizes in file */
-               num_sources,            /* Number of sources in file */
-               num_types;              /* Number of types in file */
-  char         line[2048],             /* Current line */
-               *value,                 /* Pointer to value in line */
-               *valueptr,              /* Pointer into value */
-               pwg_keyword[128],       /* PWG keyword */
-               ppd_keyword[PPD_MAX_NAME];
-                                       /* PPD keyword */
-  _pwg_output_mode_t output_mode;      /* Output mode for preset */
-  _pwg_print_quality_t print_quality;  /* Print quality for preset */
-
-
-  DEBUG_printf(("_pwgCreateWithFile(filename=\"%s\")", filename));
-
- /*
-  * Range check input...
-  */
-
-  if (!filename)
-  {
-    _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
-    return (NULL);
-  }
-
- /*
-  * Open the file...
-  */
-
-  if ((fp = cupsFileOpen(filename, "r")) == NULL)
-  {
-    _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-    return (NULL);
-  }
-
- /*
-  * Allocate the mapping data structure...
-  */
-
-  if ((pwg = calloc(1, sizeof(_pwg_t))) == NULL)
-  {
-    DEBUG_puts("_pwgCreateWithFile: Unable to allocate pwg_t.");
-    _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-    goto create_error;
-  }
-
- /*
-  * Read the file...
-  */
-
-  linenum     = 0;
-  num_bins    = 0;
-  num_sizes   = 0;
-  num_sources = 0;
-  num_types   = 0;
-
-  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
-  {
-    DEBUG_printf(("_pwgCreateWithFile: line=\"%s\", value=\"%s\", linenum=%d",
-                 line, value, linenum));
-
-    if (!value)
-    {
-      DEBUG_printf(("_pwgCreateWithFile: Missing value on line %d.", linenum));
-      _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-      goto create_error;
-    }
-    else if (!strcasecmp(line, "NumBins"))
-    {
-      if (num_bins > 0)
-      {
-        DEBUG_puts("_pwgCreateWithFile: NumBins listed multiple times.");
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((num_bins = atoi(value)) <= 0 || num_bins > 65536)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad NumBins value %d on line %d.",
-                     num_sizes, linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((pwg->bins = calloc(num_bins, sizeof(_pwg_map_t))) == NULL)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d bins.",
-                     num_sizes));
-       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-       goto create_error;
-      }
-    }
-    else if (!strcasecmp(line, "Bin"))
-    {
-      if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad Bin on line %d.", linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if (pwg->num_bins >= num_bins)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Too many Bin's on line %d.",
-                     linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      map      = pwg->bins + pwg->num_bins;
-      map->pwg = _cupsStrAlloc(pwg_keyword);
-      map->ppd = _cupsStrAlloc(ppd_keyword);
-
-      pwg->num_bins ++;
-    }
-    else if (!strcasecmp(line, "NumSizes"))
-    {
-      if (num_sizes > 0)
-      {
-        DEBUG_puts("_pwgCreateWithFile: NumSizes listed multiple times.");
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad NumSizes value %d on line %d.",
-                     num_sizes, linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((pwg->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sizes.",
-                     num_sizes));
-       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-       goto create_error;
-      }
-    }
-    else if (!strcasecmp(line, "Size"))
-    {
-      if (pwg->num_sizes >= num_sizes)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Too many Size's on line %d.",
-                     linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      size = pwg->sizes + pwg->num_sizes;
-
-      if (sscanf(value, "%127s%40s%d%d%d%d%d%d", pwg_keyword, ppd_keyword,
-                &(size->width), &(size->length), &(size->left),
-                &(size->bottom), &(size->right), &(size->top)) != 8)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad Size on line %d.", linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      size->map.pwg = _cupsStrAlloc(pwg_keyword);
-      size->map.ppd = _cupsStrAlloc(ppd_keyword);
-
-      pwg->num_sizes ++;
-    }
-    else if (!strcasecmp(line, "CustomSize"))
-    {
-      if (pwg->custom_max_width > 0)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Too many CustomSize's on line %d.",
-                     linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if (sscanf(value, "%d%d%d%d%d%d%d%d", &(pwg->custom_max_width),
-                 &(pwg->custom_max_length), &(pwg->custom_min_width),
-                &(pwg->custom_min_length), &(pwg->custom_size.left),
-                &(pwg->custom_size.bottom), &(pwg->custom_size.right),
-                &(pwg->custom_size.top)) != 8)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad CustomSize on line %d.", linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
-                      pwg->custom_max_width, pwg->custom_max_length);
-      pwg->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
-
-      _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
-                      pwg->custom_min_width, pwg->custom_min_length);
-      pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
-    }
-    else if (!strcasecmp(line, "SourceOption"))
-    {
-      pwg->source_option = _cupsStrAlloc(value);
-    }
-    else if (!strcasecmp(line, "NumSources"))
-    {
-      if (num_sources > 0)
-      {
-        DEBUG_puts("_pwgCreateWithFile: NumSources listed multiple times.");
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((num_sources = atoi(value)) <= 0 || num_sources > 65536)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad NumSources value %d on line %d.",
-                     num_sources, linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((pwg->sources = calloc(num_sources, sizeof(_pwg_map_t))) == NULL)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sources.",
-                     num_sources));
-       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-       goto create_error;
-      }
-    }
-    else if (!strcasecmp(line, "Source"))
-    {
-      if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad Source on line %d.", linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if (pwg->num_sources >= num_sources)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Too many Source's on line %d.",
-                     linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      map      = pwg->sources + pwg->num_sources;
-      map->pwg = _cupsStrAlloc(pwg_keyword);
-      map->ppd = _cupsStrAlloc(ppd_keyword);
-
-      pwg->num_sources ++;
-    }
-    else if (!strcasecmp(line, "NumTypes"))
-    {
-      if (num_types > 0)
-      {
-        DEBUG_puts("_pwgCreateWithFile: NumTypes listed multiple times.");
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((num_types = atoi(value)) <= 0 || num_types > 65536)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad NumTypes value %d on line %d.",
-                     num_types, linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if ((pwg->types = calloc(num_types, sizeof(_pwg_map_t))) == NULL)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d types.",
-                     num_types));
-       _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-       goto create_error;
-      }
-    }
-    else if (!strcasecmp(line, "Type"))
-    {
-      if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad Type on line %d.", linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      if (pwg->num_types >= num_types)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Too many Type's on line %d.",
-                     linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      map      = pwg->types + pwg->num_types;
-      map->pwg = _cupsStrAlloc(pwg_keyword);
-      map->ppd = _cupsStrAlloc(ppd_keyword);
-
-      pwg->num_types ++;
-    }
-    else if (!strcasecmp(line, "Preset"))
-    {
-     /*
-      * Preset output-mode print-quality name=value ...
-      */
-
-      output_mode   = (_pwg_output_mode_t)strtol(value, &valueptr, 10);
-      print_quality = (_pwg_print_quality_t)strtol(valueptr, &valueptr, 10);
-
-      if (output_mode < _PWG_OUTPUT_MODE_MONOCHROME ||
-          output_mode >= _PWG_OUTPUT_MODE_MAX ||
-         print_quality < _PWG_PRINT_QUALITY_DRAFT ||
-         print_quality >= _PWG_PRINT_QUALITY_MAX ||
-         valueptr == value || !*valueptr)
-      {
-        DEBUG_printf(("_pwgCreateWithFile: Bad Preset on line %d.", linenum));
-       _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-       goto create_error;
-      }
-
-      pwg->num_presets[output_mode][print_quality] =
-          cupsParseOptions(valueptr, 0,
-                          pwg->presets[output_mode] + print_quality);
-    }
-    else if (!strcasecmp(line, "SidesOption"))
-      pwg->sides_option = _cupsStrAlloc(value);
-    else if (!strcasecmp(line, "Sides1Sided"))
-      pwg->sides_1sided = _cupsStrAlloc(value);
-    else if (!strcasecmp(line, "Sides2SidedLong"))
-      pwg->sides_2sided_long = _cupsStrAlloc(value);
-    else if (!strcasecmp(line, "Sides2SidedShort"))
-      pwg->sides_2sided_short = _cupsStrAlloc(value);
-    else
-    {
-      DEBUG_printf(("_pwgCreateWithFile: Unknown %s on line %d.", line,
-                   linenum));
-      _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-      goto create_error;
-    }
-  }
-
-  if (pwg->num_sizes < num_sizes)
-  {
-    DEBUG_printf(("_pwgCreateWithFile: Not enough sizes (%d < %d).",
-                  pwg->num_sizes, num_sizes));
-    _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-    goto create_error;
-  }
-
-  if (pwg->num_sources < num_sources)
-  {
-    DEBUG_printf(("_pwgCreateWithFile: Not enough sources (%d < %d).",
-                  pwg->num_sources, num_sources));
-    _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-    goto create_error;
-  }
-
-  if (pwg->num_types < num_types)
-  {
-    DEBUG_printf(("_pwgCreateWithFile: Not enough types (%d < %d).",
-                  pwg->num_types, num_types));
-    _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
-    goto create_error;
-  }
-
-  cupsFileClose(fp);
-
-  return (pwg);
-
- /*
-  * If we get here the file was bad - free any data and return...
-  */
-
-  create_error:
-
-  cupsFileClose(fp);
-  _pwgDestroy(pwg);
-
-  return (NULL);
-}
-
-
-/*
- * '_pwgDestroy()' - Free all memory used for PWG mapping data.
- */
-
-void
-_pwgDestroy(_pwg_t *pwg)               /* I - PWG mapping data */
-{
-  int          i;                      /* Looping var */
-  _pwg_map_t   *map;                   /* Current map */
-  _pwg_size_t  *size;                  /* Current size */
-
-
- /*
-  * Range check input...
-  */
-
-  if (!pwg)
-    return;
-
- /*
-  * Free memory as needed...
-  */
-
-  if (pwg->bins)
-  {
-    for (i = pwg->num_bins, map = pwg->bins; i > 0; i --, map ++)
-    {
-      _cupsStrFree(map->pwg);
-      _cupsStrFree(map->ppd);
-    }
-
-    free(pwg->bins);
-  }
-
-  if (pwg->sizes)
-  {
-    for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
-    {
-      _cupsStrFree(size->map.pwg);
-      _cupsStrFree(size->map.ppd);
-    }
-
-    free(pwg->sizes);
-  }
-
-  if (pwg->source_option)
-    _cupsStrFree(pwg->source_option);
-
-  if (pwg->sources)
-  {
-    for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++)
-    {
-      _cupsStrFree(map->pwg);
-      _cupsStrFree(map->ppd);
-    }
-
-    free(pwg->sources);
-  }
-
-  if (pwg->types)
-  {
-    for (i = pwg->num_types, map = pwg->types; i > 0; i --, map ++)
-    {
-      _cupsStrFree(map->pwg);
-      _cupsStrFree(map->ppd);
-    }
-
-    free(pwg->types);
-  }
-
-  if (pwg->custom_max_keyword)
-    _cupsStrFree(pwg->custom_max_keyword);
-
-  if (pwg->custom_min_keyword)
-    _cupsStrFree(pwg->custom_min_keyword);
-
-  free(pwg);
-}
-
-
-/*
- * '_pwgWriteFile()' - Write PWG mapping data to a file.
- */
-
-int                                    /* O - 1 on success, 0 on failure */
-_pwgWriteFile(_pwg_t     *pwg,         /* I - PWG mapping data */
-              const char *filename)    /* I - File to write */
-{
-  int          i, j, k;                /* Looping vars */
-  cups_file_t  *fp;                    /* Output file */
-  _pwg_size_t  *size;                  /* Current size */
-  _pwg_map_t   *map;                   /* Current map */
-  cups_option_t        *option;                /* Current option */
-
-
- /*
-  * Range check input...
-  */
-
-  if (!pwg || !filename)
-  {
-    _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
-    return (0);
-  }
-
- /*
-  * Open the file and write with compression...
-  */
-
-  if ((fp = cupsFileOpen(filename, "w9")) == NULL)
-  {
-    _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
-    return (0);
-  }
-
- /*
-  * Standard header...
-  */
-
-  cupsFilePuts(fp, "#CUPS-PWGPPD\n");
-
- /*
-  * Output bins...
-  */
-
-  if (pwg->num_bins > 0)
-  {
-    cupsFilePrintf(fp, "NumBins %d\n", pwg->num_bins);
-    for (i = pwg->num_bins, map = pwg->bins; i > 0; i --, map ++)
-      cupsFilePrintf(fp, "Bin %s %s\n", map->pwg, map->ppd);
-  }
-
- /*
-  * Media sizes...
-  */
-
-  cupsFilePrintf(fp, "NumSizes %d\n", pwg->num_sizes);
-  for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
-    cupsFilePrintf(fp, "Size %s %s %d %d %d %d %d %d\n", size->map.pwg,
-                  size->map.ppd, size->width, size->length, size->left,
-                  size->bottom, size->right, size->top);
-  if (pwg->custom_max_width > 0)
-    cupsFilePrintf(fp, "CustomSize %d %d %d %d %d %d %d %d\n",
-                   pwg->custom_max_width, pwg->custom_max_length,
-                  pwg->custom_min_width, pwg->custom_min_length,
-                  pwg->custom_size.left, pwg->custom_size.bottom,
-                  pwg->custom_size.right, pwg->custom_size.top);
-
- /*
-  * Media sources...
-  */
-
-  if (pwg->source_option)
-    cupsFilePrintf(fp, "SourceOption %s\n", pwg->source_option);
-
-  if (pwg->num_sources > 0)
-  {
-    cupsFilePrintf(fp, "NumSources %d\n", pwg->num_sources);
-    for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++)
-      cupsFilePrintf(fp, "Source %s %s\n", map->pwg, map->ppd);
-  }
-
- /*
-  * Media types...
-  */
-
-  if (pwg->num_types > 0)
-  {
-    cupsFilePrintf(fp, "NumTypes %d\n", pwg->num_types);
-    for (i = pwg->num_types, map = pwg->types; i > 0; i --, map ++)
-      cupsFilePrintf(fp, "Type %s %s\n", map->pwg, map->ppd);
-  }
-
- /*
-  * Presets...
-  */
-
-  for (i = _PWG_OUTPUT_MODE_MONOCHROME; i < _PWG_OUTPUT_MODE_MAX; i ++)
-    for (j = _PWG_PRINT_QUALITY_DRAFT; j < _PWG_PRINT_QUALITY_MAX; j ++)
-      if (pwg->num_presets[i][j])
-      {
-       cupsFilePrintf(fp, "Preset %d %d", i, j);
-       for (k = pwg->num_presets[i][j], option = pwg->presets[i][j];
-            k > 0;
-            k --, option ++)
-         cupsFilePrintf(fp, " %s=%s", option->name, option->value);
-       cupsFilePutChar(fp, '\n');
-      }
-
- /*
-  * Duplex/sides...
-  */
-
-  if (pwg->sides_option)
-    cupsFilePrintf(fp, "SidesOption %s\n", pwg->sides_option);
-
-  if (pwg->sides_1sided)
-    cupsFilePrintf(fp, "Sides1Sided %s\n", pwg->sides_1sided);
-
-  if (pwg->sides_2sided_long)
-    cupsFilePrintf(fp, "Sides2SidedLong %s\n", pwg->sides_2sided_long);
-
-  if (pwg->sides_2sided_short)
-    cupsFilePrintf(fp, "Sides2SidedShort %s\n", pwg->sides_2sided_short);
-
- /*
-  * Close and return...
-  */
-
-  return (!cupsFileClose(fp));
-}
-
-
-/*
- * End of "$Id$".
- */
index f15e11e4c2da9b159f871d1fa5d04b231abac4fa..8097bbceeff2d6f23d4c61f2737f90a130d73a33 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   PWG test program for CUPS.
  *
- *   Copyright 2009-2010 by Apple Inc.
+ *   Copyright 2009-2011 by Apple Inc.
  *
  *   These coded instructions, statements, and computer programs are the
  *   property of Apple Inc. and are protected by Federal copyright
@@ -15,9 +15,6 @@
  *
  * Contents:
  *
- *   main()          - Main entry.
- *   test_pagesize() - Test the PWG mapping functions.
- *   test_pwg()      - Test the PWG mapping functions.
  */
 
 /*
@@ -32,9 +29,9 @@
  * Local functions...
  */
 
-static int     test_pwg(_pwg_t *pwg, ppd_file_t *ppd);
-static int     test_pagesize(_pwg_t *pwg, ppd_file_t *ppd,
+static int     test_pagesize(_ppd_cache_t *pc, ppd_file_t *ppd,
                              const char *ppdsize);
+static int     test_ppd_cache(_ppd_cache_t *pc, ppd_file_t *ppd);
 
 
 /*
@@ -48,7 +45,7 @@ main(int  argc,                               /* I - Number of command-line args */
   int          status;                 /* Status of tests (0 = success, 1 = fail) */
   const char   *ppdfile;               /* PPD filename */
   ppd_file_t   *ppd;                   /* PPD file */
-  _pwg_t       *pwg;                   /* PWG mapping data */
+  _ppd_cache_t *pc;                    /* PPD cache and PWG mapping data */
   _pwg_media_t *pwgmedia;              /* PWG media size */
 
 
@@ -78,8 +75,8 @@ main(int  argc,                               /* I - Number of command-line args */
   else
     puts("PASS");
 
-  fputs("_pwgCreateWithPPD(ppd): ", stdout);
-  if ((pwg = _pwgCreateWithPPD(ppd)) == NULL)
+  fputs("_ppdCacheCreateWithPPD(ppd): ", stdout);
+  if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
   {
     puts("FAIL");
     status ++;
@@ -87,7 +84,7 @@ main(int  argc,                               /* I - Number of command-line args */
   else
   {
     puts("PASS");
-    status += test_pwg(pwg, ppd);
+    status += test_ppd_cache(pc, ppd);
 
     if (argc == 3)
     {
@@ -112,13 +109,14 @@ main(int  argc,                           /* I - Number of command-line args */
          media = NULL;
 
        if (media)
-         printf("_pwgGetPageSize(media=%s): ", media->values[0].string.text);
+         printf("_ppdCacheGetPageSize(media=%s): ",
+                media->values[0].string.text);
        else
-         fputs("_pwgGetPageSize(media-col): ", stdout);
+         fputs("_ppdCacheGetPageSize(media-col): ", stdout);
 
         fflush(stdout);
 
-       if ((pagesize = _pwgGetPageSize(pwg, job, NULL, NULL)) == NULL)
+       if ((pagesize = _ppdCacheGetPageSize(pc, job, NULL, NULL)) == NULL)
        {
          puts("FAIL (Not Found)");
          status = 1;
@@ -142,11 +140,11 @@ main(int  argc,                           /* I - Number of command-line args */
     }
 
    /*
-    * _pwgDestroy should never fail...
+    * _ppdCacheDestroy should never fail...
     */
 
-    fputs("_pwgDestroy(pwg): ", stdout);
-    _pwgDestroy(pwg);
+    fputs("_ppdCacheDestroy(pc): ", stdout);
+    _ppdCacheDestroy(pc);
     puts("PASS");
   }
 
@@ -268,9 +266,9 @@ main(int  argc,                             /* I - Number of command-line args */
  */
 
 static int                             /* O - 1 on failure, 0 on success */
-test_pagesize(_pwg_t     *pwg,         /* I - PWG mapping data */
-              ppd_file_t *ppd,         /* I - PPD file */
-             const char *ppdsize)      /* I - PPD page size */
+test_pagesize(_ppd_cache_t *pc,                /* I - PWG mapping data */
+              ppd_file_t   *ppd,       /* I - PPD file */
+             const char   *ppdsize)    /* I - PPD page size */
 {
   int          status = 0;             /* Return status */
   ipp_t                *job;                   /* Job attributes */
@@ -279,10 +277,10 @@ test_pagesize(_pwg_t     *pwg,            /* I - PWG mapping data */
 
   if (ppdPageSize(ppd, ppdsize))
   {
-    printf("_pwgGetPageSize(keyword=%s): ", ppdsize);
+    printf("_ppdCacheGetPageSize(keyword=%s): ", ppdsize);
     fflush(stdout);
 
-    if ((pagesize = _pwgGetPageSize(pwg, NULL, ppdsize, NULL)) == NULL)
+    if ((pagesize = _ppdCacheGetPageSize(pc, NULL, ppdsize, NULL)) == NULL)
     {
       puts("FAIL (Not Found)");
       status = 1;
@@ -298,10 +296,10 @@ test_pagesize(_pwg_t     *pwg,            /* I - PWG mapping data */
     job = ippNew();
     ippAddString(job, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media", NULL, ppdsize);
 
-    printf("_pwgGetPageSize(media=%s): ", ppdsize);
+    printf("_ppdCacheGetPageSize(media=%s): ", ppdsize);
     fflush(stdout);
 
-    if ((pagesize = _pwgGetPageSize(pwg, job, NULL, NULL)) == NULL)
+    if ((pagesize = _ppdCacheGetPageSize(pc, job, NULL, NULL)) == NULL)
     {
       puts("FAIL (Not Found)");
       status = 1;
@@ -322,16 +320,16 @@ test_pagesize(_pwg_t     *pwg,            /* I - PWG mapping data */
 
 
 /*
- * 'test_pwg()' - Test the PWG mapping functions.
+ * 'test_ppd_cache()' - Test the PPD cache functions.
  */
 
 static int                             /* O - 1 on failure, 0 on success */
-test_pwg(_pwg_t     *pwg,              /* I - PWG mapping data */
-         ppd_file_t *ppd)              /* I - PPD file */
+test_ppd_cache(_ppd_cache_t *pc,       /* I - PWG mapping data */
+               ppd_file_t   *ppd)      /* I - PPD file */
 {
   int          i,                      /* Looping var */
                status = 0;             /* Return status */
-  _pwg_t       *pwg2;                  /* Loaded data */
+  _ppd_cache_t *pc2;                   /* Loaded data */
   _pwg_size_t  *size,                  /* Size from original */
                *size2;                 /* Size from saved */
   _pwg_map_t   *map,                   /* Map from original */
@@ -342,8 +340,8 @@ test_pwg(_pwg_t     *pwg,           /* I - PWG mapping data */
   * Verify that we can write and read back the same data...
   */
 
-  fputs("_pwgWriteFile(test.pwg): ", stdout);
-  if (!_pwgWriteFile(pwg, "test.pwg"))
+  fputs("_ppdCacheWriteFile(test.pwg): ", stdout);
+  if (!_ppdCacheWriteFile(pc, "test.pwg"))
   {
     puts("FAIL");
     status ++;
@@ -351,27 +349,27 @@ test_pwg(_pwg_t     *pwg,         /* I - PWG mapping data */
   else
     puts("PASS");
 
-  fputs("_pwgCreateWithFile(test.pwg): ", stdout);
-  if ((pwg2 = _pwgCreateWithFile("test.pwg")) == NULL)
+  fputs("_ppdCacheCreateWithFile(test.pwg): ", stdout);
+  if ((pc2 = _ppdCacheCreateWithFile("test.pwg")) == NULL)
   {
     puts("FAIL");
     status ++;
   }
   else
   {
-    if (pwg2->num_sizes != pwg->num_sizes)
+    if (pc2->num_sizes != pc->num_sizes)
     {
       if (!status)
         puts("FAIL");
 
-      printf("    SAVED num_sizes=%d, ORIG num_sizes=%d\n", pwg2->num_sizes,
-             pwg->num_sizes);
+      printf("    SAVED num_sizes=%d, ORIG num_sizes=%d\n", pc2->num_sizes,
+             pc->num_sizes);
 
       status ++;
     }
     else
     {
-      for (i = pwg->num_sizes, size = pwg->sizes, size2 = pwg2->sizes;
+      for (i = pc->num_sizes, size = pc->sizes, size2 = pc2->sizes;
            i > 0;
           i --, size ++, size2 ++)
       {
@@ -424,7 +422,7 @@ test_pwg(_pwg_t     *pwg,           /* I - PWG mapping data */
        }
       }
 
-      for (i = pwg->num_sources, map = pwg->sources, map2 = pwg2->sources;
+      for (i = pc->num_sources, map = pc->sources, map2 = pc2->sources;
            i > 0;
           i --, map ++, map2 ++)
       {
@@ -447,7 +445,7 @@ test_pwg(_pwg_t     *pwg,           /* I - PWG mapping data */
        }
       }
 
-      for (i = pwg->num_types, map = pwg->types, map2 = pwg2->types;
+      for (i = pc->num_types, map = pc->types, map2 = pc2->types;
            i > 0;
           i --, map ++, map2 ++)
       {
@@ -474,17 +472,17 @@ test_pwg(_pwg_t     *pwg,         /* I - PWG mapping data */
     if (!status)
       puts("PASS");
 
-    _pwgDestroy(pwg2);
+    _ppdCacheDestroy(pc2);
   }
 
  /*
   * Test PageSize mapping code...
   */
 
-  status += test_pagesize(pwg, ppd, "Letter");
-  status += test_pagesize(pwg, ppd, "na-letter");
-  status += test_pagesize(pwg, ppd, "A4");
-  status += test_pagesize(pwg, ppd, "iso-a4");
+  status += test_pagesize(pc, ppd, "Letter");
+  status += test_pagesize(pc, ppd, "na-letter");
+  status += test_pagesize(pc, ppd, "A4");
+  status += test_pagesize(pc, ppd, "iso-a4");
 
   return (status);
 }
index 4449392e286ead3ef47158f341b9310587eb0228..d24ce04bed083796ca5408dac4645cfbcb40d10f 100644 (file)
@@ -1540,7 +1540,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) &&
       !ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
-      _pwgGetPageSize(printer->pwg, con->request, NULL, &exact))
+      _ppdCacheGetPageSize(printer->pc, con->request, NULL, &exact))
   {
     if (!exact &&
         (media_col = ippFindAttribute(con->request, "media-col",
index 792210d7ace331bb28668023db90b734d3ffa4ab..ee6a38b9228e61f2555c33cd75a358c08b41cd39 100644 (file)
@@ -3034,12 +3034,13 @@ get_options(cupsd_job_t *job,           /* I - Job */
   char                 *optptr,        /* Pointer to options */
                        *valptr;        /* Pointer in value string */
   ipp_attribute_t      *attr;          /* Current attribute */
-  _pwg_t               *pwg;           /* PWG->PPD mapping data */
+  _ppd_cache_t         *pc;            /* PPD cache and mapping data */
   int                  num_pwgppds;    /* Number of PWG->PPD options */
   cups_option_t                *pwgppds,       /* PWG->PPD options */
                        *pwgppd,        /* Current PWG->PPD option */
                        *preset;        /* Current preset option */
-  int                  output_mode,    /* Output mode (if any) */
+  int                  print_color_mode,
+                                       /* Output mode (if any) */
                        print_quality;  /* Print quality (if any) */
   const char           *ppd;           /* PPD option choice */
   int                  exact;          /* Did we get an exact match? */
@@ -3055,28 +3056,31 @@ get_options(cupsd_job_t *job,           /* I - Job */
   * First build an options array for any PWG->PPD mapped option/choice pairs.
   */
 
-  pwg         = job->printer->pwg;
+  pc          = job->printer->pc;
   num_pwgppds = 0;
   pwgppds     = NULL;
 
-  if (pwg &&
+  if (pc &&
       !ippFindAttribute(job->attrs,
                         "com.apple.print.DocumentTicket.PMSpoolFormat",
                        IPP_TAG_ZERO) &&
       !ippFindAttribute(job->attrs, "APPrinterPreset", IPP_TAG_ZERO) &&
       (ippFindAttribute(job->attrs, "output-mode", IPP_TAG_ZERO) ||
+       ippFindAttribute(job->attrs, "print-color-mode", IPP_TAG_ZERO) ||
        ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ZERO)))
   {
    /*
     * Map output-mode and print-quality to a preset...
     */
 
-    if ((attr = ippFindAttribute(job->attrs, "output-mode",
-                                IPP_TAG_KEYWORD)) != NULL &&
-       !strcmp(attr->values[0].string.text, "monochrome"))
-      output_mode = _PWG_OUTPUT_MODE_MONOCHROME;
+    if ((attr = ippFindAttribute(job->attrs, "print-color-mode",
+                                IPP_TAG_KEYWORD)) == NULL)
+      attr = ippFindAttribute(job->attrs, "output-mode", IPP_TAG_KEYWORD);
+
+    if (attr && !strcmp(attr->values[0].string.text, "monochrome"))
+      print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
     else
-      output_mode = _PWG_OUTPUT_MODE_COLOR;
+      print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
 
     if ((attr = ippFindAttribute(job->attrs, "print-quality",
                                 IPP_TAG_ENUM)) != NULL &&
@@ -3086,33 +3090,33 @@ get_options(cupsd_job_t *job,           /* I - Job */
     else
       print_quality = _PWG_PRINT_QUALITY_NORMAL;
 
-    if (pwg->num_presets[output_mode][print_quality] == 0)
+    if (pc->num_presets[print_color_mode][print_quality] == 0)
     {
      /*
       * Try to find a preset that works so that we maximize the chances of us
       * getting a good print using IPP attributes.
       */
 
-      if (pwg->num_presets[output_mode][_PWG_PRINT_QUALITY_NORMAL] > 0)
+      if (pc->num_presets[print_color_mode][_PWG_PRINT_QUALITY_NORMAL] > 0)
         print_quality = _PWG_PRINT_QUALITY_NORMAL;
-      else if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][print_quality] > 0)
-        output_mode = _PWG_OUTPUT_MODE_COLOR;
+      else if (pc->num_presets[_PWG_PRINT_COLOR_MODE_COLOR][print_quality] > 0)
+        print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
       else
       {
-        print_quality = _PWG_PRINT_QUALITY_NORMAL;
-        output_mode   = _PWG_OUTPUT_MODE_COLOR;
+        print_quality    = _PWG_PRINT_QUALITY_NORMAL;
+        print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
       }
     }
 
-    if (pwg->num_presets[output_mode][print_quality] > 0)
+    if (pc->num_presets[print_color_mode][print_quality] > 0)
     {
      /*
       * Copy the preset options as long as the corresponding names are not
       * already defined in the IPP request...
       */
 
-      for (i = pwg->num_presets[output_mode][print_quality],
-              preset = pwg->presets[output_mode][print_quality];
+      for (i = pc->num_presets[print_color_mode][print_quality],
+              preset = pc->presets[print_color_mode][print_quality];
           i > 0;
           i --, preset ++)
       {
@@ -3123,13 +3127,13 @@ get_options(cupsd_job_t *job,           /* I - Job */
     }
   }
 
-  if (pwg)
+  if (pc)
   {
     if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) &&
        !ippFindAttribute(job->attrs, "HPPaperSource", IPP_TAG_ZERO))
     {
-      if ((ppd = _pwgGetInputSlot(pwg, job->attrs, NULL)) != NULL)
-       num_pwgppds = cupsAddOption(pwg->source_option, ppd, num_pwgppds,
+      if ((ppd = _ppdCacheGetInputSlot(pc, job->attrs, NULL)) != NULL)
+       num_pwgppds = cupsAddOption(pc->source_option, ppd, num_pwgppds,
                                    &pwgppds);
       else if (!ippFindAttribute(job->attrs, "AP_D_InputSlot", IPP_TAG_ZERO))
        num_pwgppds = cupsAddOption("AP_D_InputSlot", "", num_pwgppds,
@@ -3137,12 +3141,12 @@ get_options(cupsd_job_t *job,           /* I - Job */
     }
 
     if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) &&
-       (ppd = _pwgGetMediaType(pwg, job->attrs, NULL)) != NULL)
+       (ppd = _ppdCacheGetMediaType(pc, job->attrs, NULL)) != NULL)
       num_pwgppds = cupsAddOption("MediaType", ppd, num_pwgppds, &pwgppds);
 
     if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) &&
        !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) &&
-       (ppd = _pwgGetPageSize(pwg, job->attrs, NULL, &exact)) != NULL)
+       (ppd = _ppdCacheGetPageSize(pc, job->attrs, NULL, &exact)) != NULL)
     {
       num_pwgppds = cupsAddOption("PageSize", ppd, num_pwgppds, &pwgppds);
 
@@ -3155,7 +3159,7 @@ get_options(cupsd_job_t *job,             /* I - Job */
                                 IPP_TAG_ZERO)) != NULL &&
        (attr->value_tag == IPP_TAG_KEYWORD ||
         attr->value_tag == IPP_TAG_NAME) &&
-       (ppd = _pwgGetOutputBin(pwg, attr->values[0].string.text)) != NULL)
+       (ppd = _ppdCacheGetOutputBin(pc, attr->values[0].string.text)) != NULL)
     {
      /*
       * Map output-bin to OutputBin option...
@@ -3164,8 +3168,8 @@ get_options(cupsd_job_t *job,             /* I - Job */
       num_pwgppds = cupsAddOption("OutputBin", ppd, num_pwgppds, &pwgppds);
     }
 
-    if (pwg->sides_option &&
-        !ippFindAttribute(job->attrs, pwg->sides_option, IPP_TAG_ZERO) &&
+    if (pc->sides_option &&
+        !ippFindAttribute(job->attrs, pc->sides_option, IPP_TAG_ZERO) &&
        (attr = ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD)) != NULL)
     {
      /*
@@ -3173,13 +3177,13 @@ get_options(cupsd_job_t *job,           /* I - Job */
       */
 
       if (!strcmp(attr->values[0].string.text, "one-sided"))
-        num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_1sided,
+        num_pwgppds = cupsAddOption(pc->sides_option, pc->sides_1sided,
                                    num_pwgppds, &pwgppds);
       else if (!strcmp(attr->values[0].string.text, "two-sided-long-edge"))
-        num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_long,
+        num_pwgppds = cupsAddOption(pc->sides_option, pc->sides_2sided_long,
                                    num_pwgppds, &pwgppds);
       else if (!strcmp(attr->values[0].string.text, "two-sided-short-edge"))
-        num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_short,
+        num_pwgppds = cupsAddOption(pc->sides_option, pc->sides_2sided_short,
                                    num_pwgppds, &pwgppds);
     }
   }
index 696b98df71ec6fa1555a0c4192739e0798beba7a..d04c6c1b9f3888e47f63d9fd92f1e817fa8993f1 100644 (file)
@@ -4021,13 +4021,13 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
   ippDelete(p->ppd_attrs);
   p->ppd_attrs = ippNew();
 
-  _pwgDestroy(p->pwg);
-  p->pwg = NULL;
+  _ppdCacheDestroy(p->pc);
+  p->pc = NULL;
 
   if (pwg_info.st_mtime >= ppd_info.st_mtime)
-    p->pwg = _pwgCreateWithFile(pwg_name);
+    p->pc = _ppdCacheCreateWithFile(pwg_name);
 
-  if (cache_info.st_mtime >= ppd_info.st_mtime && p->pwg &&
+  if (cache_info.st_mtime >= ppd_info.st_mtime && p->pc &&
       (cache = cupsFileOpen(cache_name, "r")) != NULL)
   {
    /*
@@ -4052,8 +4052,8 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
 
   cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
 
-  _pwgDestroy(p->pwg);
-  p->pwg = NULL;
+  _ppdCacheDestroy(p->pc);
+  p->pc = NULL;
 
   cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Loading %s...", ppd_name);
 
@@ -4072,7 +4072,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
     * Add make/model and other various attributes...
     */
 
-    p->pwg = _pwgCreateWithPPD(ppd);
+    p->pc = _ppdCacheCreateWithPPD(ppd);
 
     ppdMarkDefaults(ppd);
 
@@ -4175,7 +4175,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
     * Add media options from the PPD file...
     */
 
-    if (ppd->num_sizes == 0 || !p->pwg)
+    if (ppd->num_sizes == 0 || !p->pc)
     {
       if (!ppdFindAttr(ppd, "APScannerOnly", NULL))
        cupsdLogMessage(CUPSD_LOG_CRIT,
@@ -4194,7 +4194,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
       */
 
       if ((size = ppdPageSize(ppd, NULL)) != NULL)
-        pwgsize = _pwgGetSize(p->pwg, size->name);
+        pwgsize = _ppdCacheGetSize(p->pc, size->name);
       else
         pwgsize = NULL;
 
@@ -4214,12 +4214,12 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
        media_type = ppdFindMarkedChoice(ppd, "MediaType");
        col        = new_media_col(pwgsize,
                                   input_slot ?
-                                      _pwgGetSource(p->pwg,
-                                                    input_slot->choice) :
+                                      _ppdCacheGetSource(p->pc,
+                                                         input_slot->choice) :
                                       NULL,
                                   media_type ?
-                                      _pwgGetType(p->pwg,
-                                                  media_type->choice) :
+                                      _ppdCacheGetType(p->pc,
+                                                       media_type->choice) :
                                       NULL);
 
        ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default",
@@ -4231,8 +4231,8 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
       * media-supported
       */
 
-      num_media = p->pwg->num_sizes;
-      if (p->pwg->custom_min_keyword)
+      num_media = p->pc->num_sizes;
+      if (p->pc->custom_min_keyword)
        num_media += 2;
 
       if ((attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
@@ -4241,16 +4241,16 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
       {
        val = attr->values;
 
-        for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes;
+        for (i = p->pc->num_sizes, pwgsize = p->pc->sizes;
             i > 0;
             i --, pwgsize ++, val ++)
          val->string.text = _cupsStrRetain(pwgsize->map.pwg);
 
-        if (p->pwg->custom_min_keyword)
+        if (p->pc->custom_min_keyword)
        {
-         val->string.text = _cupsStrRetain(p->pwg->custom_min_keyword);
+         val->string.text = _cupsStrRetain(p->pc->custom_min_keyword);
          val ++;
-         val->string.text = _cupsStrRetain(p->pwg->custom_max_keyword);
+         val->string.text = _cupsStrRetain(p->pc->custom_max_keyword);
         }
       }
 
@@ -4258,12 +4258,12 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
       * media-source-supported
       */
 
-      if (p->pwg->num_sources > 0 &&
+      if (p->pc->num_sources > 0 &&
           (attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                               "media-source-supported", p->pwg->num_sources,
+                               "media-source-supported", p->pc->num_sources,
                                NULL, NULL)) != NULL)
       {
-       for (i = p->pwg->num_sources, pwgsource = p->pwg->sources,
+       for (i = p->pc->num_sources, pwgsource = p->pc->sources,
                 val = attr->values;
             i > 0;
             i --, pwgsource ++, val ++)
@@ -4274,12 +4274,12 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
       * media-type-supported
       */
 
-      if (p->pwg->num_types > 0 &&
+      if (p->pc->num_types > 0 &&
           (attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                               "media-type-supported", p->pwg->num_types,
+                               "media-type-supported", p->pc->num_types,
                                NULL, NULL)) != NULL)
       {
-       for (i = p->pwg->num_types, pwgtype = p->pwg->types,
+       for (i = p->pc->num_types, pwgtype = p->pc->types,
                 val = attr->values;
             i > 0;
             i --, pwgtype ++, val ++)
@@ -4290,7 +4290,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
       * media-*-margin-supported
       */
 
-      for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0;
+      for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
           i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
           i --, pwgsize ++)
       {
@@ -4312,7 +4312,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                      "media-bottom-margin-supported", 0);
 
-      for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0;
+      for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
           i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
           i --, pwgsize ++)
       {
@@ -4334,7 +4334,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                      "media-left-margin-supported", 0);
 
-      for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0;
+      for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
           i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
           i --, pwgsize ++)
       {
@@ -4356,7 +4356,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                      "media-right-margin-supported", 0);
 
-      for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0;
+      for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
           i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
           i --, pwgsize ++)
       {
@@ -4382,23 +4382,23 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
       * media-col-database
       */
 
-      num_media = p->pwg->num_sizes;
-      if (p->pwg->num_sources)
+      num_media = p->pc->num_sizes;
+      if (p->pc->num_sources)
       {
-        if (p->pwg->num_types > 0)
-         num_media += p->pwg->num_sizes * p->pwg->num_sources *
-                      p->pwg->num_types;
+        if (p->pc->num_types > 0)
+         num_media += p->pc->num_sizes * p->pc->num_sources *
+                      p->pc->num_types;
        else
-          num_media += p->pwg->num_sizes * p->pwg->num_sources;
+          num_media += p->pc->num_sizes * p->pc->num_sources;
       }
-      else if (p->pwg->num_types)
-        num_media += p->pwg->num_sizes * p->pwg->num_types;
+      else if (p->pc->num_types)
+        num_media += p->pc->num_sizes * p->pc->num_types;
 
       if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER,
                                     "media-col-database", num_media,
                                    NULL)) != NULL)
       {
-        for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, val = attr->values;
+        for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, val = attr->values;
             i > 0;
             i --, pwgsize ++)
        {
@@ -4416,17 +4416,17 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
          * type...
          */
 
-         if (p->pwg->num_sources > 0)
+         if (p->pc->num_sources > 0)
          {
-           for (j = p->pwg->num_sources, pwgsource = p->pwg->sources;
+           for (j = p->pc->num_sources, pwgsource = p->pc->sources;
                 j > 0;
                 j --, pwgsource ++)
            {
              ppdMarkOption(ppd, "InputSlot", pwgsource->ppd);
 
-             if (p->pwg->num_types > 0)
+             if (p->pc->num_types > 0)
              {
-               for (k = p->pwg->num_types, pwgtype = p->pwg->types;
+               for (k = p->pc->num_types, pwgtype = p->pc->types;
                     k > 0;
                     k --, pwgtype ++)
                {
@@ -4445,9 +4445,9 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
              }
            }
          }
-         else if (p->pwg->num_types > 0)
+         else if (p->pc->num_types > 0)
          {
-           for (j = p->pwg->num_types, pwgtype = p->pwg->types;
+           for (j = p->pc->num_types, pwgtype = p->pc->types;
                 j > 0;
                 j --, pwgtype ++)
            {
@@ -4472,35 +4472,35 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
     * Output bin...
     */
 
-    if (p->pwg && p->pwg->num_bins > 0)
+    if (p->pc && p->pc->num_bins > 0)
     {
       attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                          "output-bin-supported", p->pwg->num_bins,
+                          "output-bin-supported", p->pc->num_bins,
                           NULL, NULL);
 
       if (attr != NULL)
       {
        for (i = 0, val = attr->values;
-            i < p->pwg->num_bins;
+            i < p->pc->num_bins;
             i ++, val ++)
-         val->string.text = _cupsStrAlloc(p->pwg->bins[i].pwg);
+         val->string.text = _cupsStrAlloc(p->pc->bins[i].pwg);
       }
 
       if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL)
       {
-       for (i = 0; i < p->pwg->num_bins; i ++)
-         if (!strcmp(p->pwg->bins[i].ppd, output_bin->defchoice))
+       for (i = 0; i < p->pc->num_bins; i ++)
+         if (!strcmp(p->pc->bins[i].ppd, output_bin->defchoice))
            break;
 
-        if (i >= p->pwg->num_bins)
+        if (i >= p->pc->num_bins)
          i = 0;
 
        ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                    "output-bin-default", NULL, p->pwg->bins[i].pwg);
+                    "output-bin-default", NULL, p->pc->bins[i].pwg);
       }
       else
         ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
-                    "output-bin-default", NULL, p->pwg->bins[0].pwg);
+                    "output-bin-default", NULL, p->pc->bins[0].pwg);
     }
     else if (((ppd_attr = ppdFindAttr(ppd, "DefaultOutputOrder",
                                      NULL)) != NULL &&
@@ -4528,7 +4528,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
     }
 
    /*
-    * output-mode...
+    * output-mode and print-color-mode...
     */
 
     if (ppd->color_device)
@@ -4543,6 +4543,11 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
                     "output-mode-supported", 2, NULL, output_modes);
       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                    "output-mode-default", NULL, "color");
+
+      ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                    "print-color-mode-supported", 2, NULL, output_modes);
+      ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                   "print-color-mode-default", NULL, "color");
     }
     else
     {
@@ -4550,6 +4555,11 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
                    "output-mode-supported", NULL, "monochrome");
       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                    "output-mode-default", NULL, "monochrome");
+
+      ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                   "print-color-mode-supported", NULL, "monochrome");
+      ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+                   "print-color-mode-default", NULL, "monochrome");
     }
 
    /*
@@ -5230,7 +5240,7 @@ load_ppd(cupsd_printer_t *p)              /* I - Printer */
 
     cupsFileClose(cache);
 
-    _pwgWriteFile(p->pwg, pwg_name);
+    _ppdCacheWriteFile(p->pc, pwg_name);
   }
   else
   {
index c0db344ac64c44165d5e02d10d13ab7fcb44fb80..f4e66913811f363e1c97fcabb99a43bfcc95b21f 100644 (file)
@@ -94,7 +94,7 @@ struct cupsd_printer_s
   cups_array_t *filters,               /* Filters for queue */
                *pre_filters,           /* Pre-filters for queue */
                *dest_types;            /* Destination types for queue */
-  _pwg_t       *pwg;                   /* PWG<->PPD mapping data */
+  _ppd_cache_t *pc;                    /* PPD cache and mapping data */
 
 #ifdef HAVE_DNSSD
   char         *reg_name,              /* Name used for service registration */