]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
libppd: Added ppdLoadAttributes, load_ppd_attributes() from ippeveprinter
authorTill Kamppeter <till.kamppeter@gmail.com>
Thu, 2 Jul 2020 21:34:20 +0000 (23:34 +0200)
committerTill Kamppeter <till.kamppeter@gmail.com>
Thu, 2 Jul 2020 21:34:20 +0000 (23:34 +0200)
Makefile.am
ppd/ppd-ipp.c [new file with mode: 0644]
ppd/ppd.h

index 8ed615fa374fc80dd72aa95c3f07a3e205139abe..c17cec6de25278c2cbe77b8019bbc29ec902336c 100644 (file)
@@ -186,6 +186,7 @@ libppd_la_SOURCES = \
        ppd/ppd-localize.c \
        ppd/ppd-mark.c \
        ppd/ppd-page.c \
+       ppd/ppd-ipp.c \
        ppd/array.c \
        ppd/array-private.h \
        ppd/debug.c \
diff --git a/ppd/ppd-ipp.c b/ppd/ppd-ipp.c
new file mode 100644 (file)
index 0000000..09a385e
--- /dev/null
@@ -0,0 +1,760 @@
+/*
+ * PPD file routines for libppd.
+ *
+ * Copyright © 2007-2019 by Apple Inc.
+ * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
+ *
+ * PostScript is a trademark of Adobe Systems, Inc.
+ */
+
+/*
+ * Include necessary headers.
+ */
+
+//#include "string-private.h"
+//#include "language-private.h"
+//#include "thread-private.h"
+#include "ppd.h"
+#include "debug-internal.h"
+
+
+/*
+ * Definitions...
+ */
+
+
+
+/*
+ * Local functions...
+ */
+
+static ipp_t           *create_media_col(const char *media, const char *source, const char *type, int width, int length, int bottom, int left, int right, int top);
+static ipp_t           *create_media_size(int width, int length);
+
+
+/*
+ * 'ppdLoadAttributes()' - Load IPP attributes from a PPD file.
+ */
+
+ipp_t *                                        /* O - IPP attributes or `NULL`
+                                          on error */
+ppdLoadAttributes(
+    const char   *ppdfile,             /* I - PPD filename */
+    cups_array_t *docformats)          /* I - document-format-supported values */
+{
+  int          i, j;                   /* Looping vars */
+  ipp_t                *attrs;                 /* Attributes */
+  ipp_attribute_t *attr;               /* Current attribute */
+  ipp_t                *col;                   /* Current collection value */
+  ppd_file_t   *ppd;                   /* PPD data */
+  ppd_attr_t   *ppd_attr;              /* PPD attribute */
+  ppd_choice_t *ppd_choice;            /* PPD choice */
+  ppd_size_t   *ppd_size;              /* Default PPD size */
+  pwg_size_t   *pwg_size,              /* Current PWG size */
+               *default_size = NULL;   /* Default PWG size */
+  const char   *default_source = NULL, /* Default media source */
+               *default_type = NULL;   /* Default media type */
+  pwg_map_t    *pwg_map;               /* Mapping from PWG to PPD keywords */
+  ppd_cache_t  *pc;                    /* PPD cache */
+  ppd_pwg_finishings_t *finishings;    /* Current finishings value */
+  const char   *template;              /* Current finishings-template value */
+  int          num_margins;            /* Number of media-xxx-margin-supported values */
+  int          margins[10];            /* media-xxx-margin-supported values */
+  int          xres,                   /* Default horizontal resolution */
+               yres;                   /* Default vertical resolution */
+  int          num_urf;                /* Number of urf-supported values */
+  const char   *urf[10];               /* urf-supported values */
+  char         urf_rs[32];             /* RS value */
+  static const int     orientation_requested_supported[4] =
+  {                                    /* orientation-requested-supported values */
+    IPP_ORIENT_PORTRAIT,
+    IPP_ORIENT_LANDSCAPE,
+    IPP_ORIENT_REVERSE_LANDSCAPE,
+    IPP_ORIENT_REVERSE_PORTRAIT
+  };
+  static const char * const overrides_supported[] =
+  {                                    /* overrides-supported */
+    "document-numbers",
+    "media",
+    "media-col",
+    "orientation-requested",
+    "pages"
+  };
+  static const char * const print_color_mode_supported[] =
+  {                                    /* print-color-mode-supported values */
+    "monochrome"
+  };
+  static const char * const print_color_mode_supported_color[] =
+  {                                    /* print-color-mode-supported values */
+    "auto",
+    "color",
+    "monochrome"
+  };
+  static const int     print_quality_supported[] =
+  {                                    /* print-quality-supported values */
+    IPP_QUALITY_DRAFT,
+    IPP_QUALITY_NORMAL,
+    IPP_QUALITY_HIGH
+  };
+  static const char * const printer_supply[] =
+  {                                    /* printer-supply values */
+    "index=1;class=receptacleThatIsFilled;type=wasteToner;unit=percent;"
+        "maxcapacity=100;level=25;colorantname=unknown;",
+    "index=2;class=supplyThatIsConsumed;type=toner;unit=percent;"
+        "maxcapacity=100;level=75;colorantname=black;"
+  };
+  static const char * const printer_supply_color[] =
+  {                                    /* printer-supply values */
+    "index=1;class=receptacleThatIsFilled;type=wasteInk;unit=percent;"
+        "maxcapacity=100;level=25;colorantname=unknown;",
+    "index=2;class=supplyThatIsConsumed;type=ink;unit=percent;"
+        "maxcapacity=100;level=75;colorantname=black;",
+    "index=3;class=supplyThatIsConsumed;type=ink;unit=percent;"
+        "maxcapacity=100;level=50;colorantname=cyan;",
+    "index=4;class=supplyThatIsConsumed;type=ink;unit=percent;"
+        "maxcapacity=100;level=33;colorantname=magenta;",
+    "index=5;class=supplyThatIsConsumed;type=ink;unit=percent;"
+        "maxcapacity=100;level=67;colorantname=yellow;"
+  };
+  static const char * const printer_supply_description[] =
+  {                                    /* printer-supply-description values */
+    "Toner Waste Tank",
+    "Black Toner"
+  };
+  static const char * const printer_supply_description_color[] =
+  {                                    /* printer-supply-description values */
+    "Ink Waste Tank",
+    "Black Ink",
+    "Cyan Ink",
+    "Magenta Ink",
+    "Yellow Ink"
+  };
+  static const char * const pwg_raster_document_type_supported[] =
+  {
+    "black_1",
+    "sgray_8"
+  };
+  static const char * const pwg_raster_document_type_supported_color[] =
+  {
+    "black_1",
+    "sgray_8",
+    "srgb_8",
+    "srgb_16"
+  };
+  static const char * const sides_supported[] =
+  {                                    /* sides-supported values */
+    "one-sided",
+    "two-sided-long-edge",
+    "two-sided-short-edge"
+  };
+
+
+ /*
+  * Open the PPD file...
+  */
+
+  if ((ppd = ppdOpenFile(ppdfile)) == NULL)
+  {
+    ppd_status_t       status;         /* Load error */
+
+    status = ppdLastError(&i);
+    fprintf(stderr, "ippeveprinter: Unable to open \"%s\": %s on line %d.", ppdfile, ppdErrorString(status), i);
+    return (NULL);
+  }
+
+  ppdMarkDefaults(ppd);
+
+  pc = ppdCacheCreateWithPPD(ppd);
+
+  if ((ppd_size = ppdPageSize(ppd, NULL)) != NULL)
+  {
+   /*
+    * Look up default size...
+    */
+
+    for (i = 0, pwg_size = pc->sizes; i < pc->num_sizes; i ++, pwg_size ++)
+    {
+      if (!strcmp(pwg_size->map.ppd, ppd_size->name))
+      {
+        default_size = pwg_size;
+        break;
+      }
+    }
+  }
+
+  if (!default_size)
+  {
+   /*
+    * Default to A4 or Letter...
+    */
+
+    for (i = 0, pwg_size = pc->sizes; i < pc->num_sizes; i ++, pwg_size ++)
+    {
+      if (!strcmp(pwg_size->map.ppd, "Letter") || !strcmp(pwg_size->map.ppd, "A4"))
+      {
+        default_size = pwg_size;
+        break;
+      }
+    }
+
+    if (!default_size)
+      default_size = pc->sizes;                /* Last resort: first size */
+  }
+
+  if ((ppd_choice = ppdFindMarkedChoice(ppd, "InputSlot")) != NULL)
+    default_source = ppdCacheGetSource(pc, ppd_choice->choice);
+
+  if ((ppd_choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
+    default_source = ppdCacheGetType(pc, ppd_choice->choice);
+
+  if ((ppd_attr = ppdFindAttr(ppd, "DefaultResolution", NULL)) != NULL)
+  {
+   /*
+    * Use the PPD-defined default resolution...
+    */
+
+    if ((i = sscanf(ppd_attr->value, "%dx%d", &xres, &yres)) == 1)
+      yres = xres;
+    else if (i < 0)
+      xres = yres = 300;
+  }
+  else
+  {
+   /*
+    * Use default of 300dpi...
+    */
+
+    xres = yres = 300;
+  }
+
+  snprintf(urf_rs, sizeof(urf_rs), "RS%d", yres < xres ? yres : xres);
+
+  num_urf = 0;
+  urf[num_urf ++] = "V1.4";
+  urf[num_urf ++] = "CP1";
+  urf[num_urf ++] = urf_rs;
+  urf[num_urf ++] = "W8";
+  if (pc->sides_2sided_long)
+    urf[num_urf ++] = "DM1";
+  if (ppd->color_device)
+    urf[num_urf ++] = "SRGB24";
+
+ /*
+  * PostScript printers accept PDF via one of the CUPS PDF to PostScript
+  * filters, along with PostScript (of course) and JPEG...
+  */
+
+  cupsArrayAdd(docformats, "application/pdf");
+  cupsArrayAdd(docformats, "application/postscript");
+  cupsArrayAdd(docformats, "image/jpeg");
+
+ /*
+  * Create the attributes...
+  */
+
+  attrs = ippNew();
+
+  /* color-supported */
+  ippAddBoolean(attrs, IPP_TAG_PRINTER, "color-supported", (char)ppd->color_device);
+
+  /* copies-default */
+  ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", 1);
+
+  /* copies-supported */
+  ippAddRange(attrs, IPP_TAG_PRINTER, "copies-supported", 1, 999);
+
+  /* document-password-supported */
+  ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "document-password-supported", 127);
+
+  /* finishing-template-supported */
+  attr = ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template-supported", cupsArrayCount(pc->templates) + 1, NULL, NULL);
+  ippSetString(attrs, &attr, 0, "none");
+  for (i = 1, template = (const char *)cupsArrayFirst(pc->templates); template; i ++, template = (const char *)cupsArrayNext(pc->templates))
+    ippSetString(attrs, &attr, i, template);
+
+  /* finishings-col-database */
+  attr = ippAddCollections(attrs, IPP_TAG_PRINTER, "finishings-col-database", cupsArrayCount(pc->templates) + 1, NULL);
+
+  col = ippNew();
+  ippAddString(col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, "none");
+  ippSetCollection(attrs, &attr, 0, col);
+  ippDelete(col);
+
+  for (i = 1, template = (const char *)cupsArrayFirst(pc->templates); template; i ++, template = (const char *)cupsArrayNext(pc->templates))
+  {
+    col = ippNew();
+    ippAddString(col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, template);
+    ippSetCollection(attrs, &attr, i, col);
+    ippDelete(col);
+  }
+
+  /* finishings-col-default */
+  col = ippNew();
+  ippAddString(col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, "none");
+  ippAddCollection(attrs, IPP_TAG_PRINTER, "finishings-col-default", col);
+  ippDelete(col);
+
+  /* finishings-col-ready */
+  attr = ippAddCollections(attrs, IPP_TAG_PRINTER, "finishings-col-ready", cupsArrayCount(pc->templates) + 1, NULL);
+
+  col = ippNew();
+  ippAddString(col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, "none");
+  ippSetCollection(attrs, &attr, 0, col);
+  ippDelete(col);
+
+  for (i = 1, template = (const char *)cupsArrayFirst(pc->templates); template; i ++, template = (const char *)cupsArrayNext(pc->templates))
+  {
+    col = ippNew();
+    ippAddString(col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, template);
+    ippSetCollection(attrs, &attr, i, col);
+    ippDelete(col);
+  }
+
+  /* finishings-col-supported */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishings-col-supported", NULL, "finishing-template");
+
+  /* finishings-default */
+  ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "finishings-default", IPP_FINISHINGS_NONE);
+
+  /* finishings-ready */
+  attr = ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "finishings-ready", cupsArrayCount(pc->finishings) + 1, NULL);
+  ippSetInteger(attrs, &attr, 0, IPP_FINISHINGS_NONE);
+  for (i = 1, finishings = (ppd_pwg_finishings_t *)cupsArrayFirst(pc->finishings); finishings; i ++, finishings = (ppd_pwg_finishings_t *)cupsArrayNext(pc->finishings))
+    ippSetInteger(attrs, &attr, i, (int)finishings->value);
+
+  /* finishings-supported */
+  attr = ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "finishings-supported", cupsArrayCount(pc->finishings) + 1, NULL);
+  ippSetInteger(attrs, &attr, 0, IPP_FINISHINGS_NONE);
+  for (i = 1, finishings = (ppd_pwg_finishings_t *)cupsArrayFirst(pc->finishings); finishings; i ++, finishings = (ppd_pwg_finishings_t *)cupsArrayNext(pc->finishings))
+    ippSetInteger(attrs, &attr, i, (int)finishings->value);
+
+  /* media-bottom-margin-supported */
+  for (i = 0, num_margins = 0, pwg_size = pc->sizes; i < pc->num_sizes && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); i ++, pwg_size ++)
+  {
+    for (j = 0; j < num_margins; j ++)
+    {
+      if (margins[j] == pwg_size->bottom)
+        break;
+    }
+
+    if (j >= num_margins)
+      margins[num_margins ++] = pwg_size->bottom;
+  }
+
+  for (i = 0; i < (num_margins - 1); i ++)
+  {
+    for (j = i + 1; j < num_margins; j ++)
+    {
+      if (margins[i] > margins[j])
+      {
+        int mtemp = margins[i];
+
+        margins[i] = margins[j];
+        margins[j] = mtemp;
+      }
+    }
+  }
+
+  ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin-supported", num_margins, margins);
+
+  /* media-col-database */
+  attr = ippAddCollections(attrs, IPP_TAG_PRINTER, "media-col-database", pc->num_sizes, NULL);
+  for (i = 0, pwg_size = pc->sizes; i < pc->num_sizes; i ++, pwg_size ++)
+  {
+    col = create_media_col(pwg_size->map.pwg, NULL, NULL, pwg_size->width, pwg_size->length, pwg_size->bottom, pwg_size->left, pwg_size->right, pwg_size->top);
+    ippSetCollection(attrs, &attr, i, col);
+    ippDelete(col);
+  }
+
+  /* media-col-default */
+  col = create_media_col(default_size->map.pwg, default_source, default_type, default_size->width, default_size->length, default_size->bottom, default_size->left, default_size->right, default_size->top);
+  ippAddCollection(attrs, IPP_TAG_PRINTER, "media-col-default", col);
+  ippDelete(col);
+
+  /* media-col-ready */
+  col = create_media_col(default_size->map.pwg, default_source, default_type, default_size->width, default_size->length, default_size->bottom, default_size->left, default_size->right, default_size->top);
+  ippAddCollection(attrs, IPP_TAG_PRINTER, "media-col-ready", col);
+  ippDelete(col);
+
+  /* media-default */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default", NULL, default_size->map.pwg);
+
+  /* media-left-margin-supported */
+  for (i = 0, num_margins = 0, pwg_size = pc->sizes; i < pc->num_sizes && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); i ++, pwg_size ++)
+  {
+    for (j = 0; j < num_margins; j ++)
+    {
+      if (margins[j] == pwg_size->left)
+        break;
+    }
+
+    if (j >= num_margins)
+      margins[num_margins ++] = pwg_size->left;
+  }
+
+  for (i = 0; i < (num_margins - 1); i ++)
+  {
+    for (j = i + 1; j < num_margins; j ++)
+    {
+      if (margins[i] > margins[j])
+      {
+        int mtemp = margins[i];
+
+        margins[i] = margins[j];
+        margins[j] = mtemp;
+      }
+    }
+  }
+
+  ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin-supported", num_margins, margins);
+
+  /* media-ready */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-ready", NULL, default_size->map.pwg);
+
+  /* media-right-margin-supported */
+  for (i = 0, num_margins = 0, pwg_size = pc->sizes; i < pc->num_sizes && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); i ++, pwg_size ++)
+  {
+    for (j = 0; j < num_margins; j ++)
+    {
+      if (margins[j] == pwg_size->right)
+        break;
+    }
+
+    if (j >= num_margins)
+      margins[num_margins ++] = pwg_size->right;
+  }
+
+  for (i = 0; i < (num_margins - 1); i ++)
+  {
+    for (j = i + 1; j < num_margins; j ++)
+    {
+      if (margins[i] > margins[j])
+      {
+        int mtemp = margins[i];
+
+        margins[i] = margins[j];
+        margins[j] = mtemp;
+      }
+    }
+  }
+
+  ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin-supported", num_margins, margins);
+
+  /* media-supported */
+  attr = ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-supported", pc->num_sizes, NULL, NULL);
+  for (i = 0, pwg_size = pc->sizes; i < pc->num_sizes; i ++, pwg_size ++)
+    ippSetString(attrs, &attr, i, pwg_size->map.pwg);
+
+  /* media-size-supported */
+  attr = ippAddCollections(attrs, IPP_TAG_PRINTER, "media-size-supported", pc->num_sizes, NULL);
+  for (i = 0, pwg_size = pc->sizes; i < pc->num_sizes; i ++, pwg_size ++)
+  {
+    col = create_media_size(pwg_size->width, pwg_size->length);
+    ippSetCollection(attrs, &attr, i, col);
+    ippDelete(col);
+  }
+
+  /* media-source-supported */
+  if (pc->num_sources > 0)
+  {
+    attr = ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-source-supported", pc->num_sources, NULL,  NULL);
+    for (i = 0, pwg_map = pc->sources; i < pc->num_sources; i ++, pwg_map ++)
+      ippSetString(attrs, &attr, i, pwg_map->pwg);
+  }
+  else
+  {
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-source-supported", NULL, "auto");
+  }
+
+  /* media-top-margin-supported */
+  for (i = 0, num_margins = 0, pwg_size = pc->sizes; i < pc->num_sizes && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); i ++, pwg_size ++)
+  {
+    for (j = 0; j < num_margins; j ++)
+    {
+      if (margins[j] == pwg_size->top)
+        break;
+    }
+
+    if (j >= num_margins)
+      margins[num_margins ++] = pwg_size->top;
+  }
+
+  for (i = 0; i < (num_margins - 1); i ++)
+  {
+    for (j = i + 1; j < num_margins; j ++)
+    {
+      if (margins[i] > margins[j])
+      {
+        int mtemp = margins[i];
+
+        margins[i] = margins[j];
+        margins[j] = mtemp;
+      }
+    }
+  }
+
+  ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin-supported", num_margins, margins);
+
+  /* media-type-supported */
+  if (pc->num_types > 0)
+  {
+    attr = ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-type-supported", pc->num_types, NULL,  NULL);
+    for (i = 0, pwg_map = pc->types; i < pc->num_types; i ++, pwg_map ++)
+      ippSetString(attrs, &attr, i, pwg_map->pwg);
+  }
+  else
+  {
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-type-supported", NULL, "auto");
+  }
+
+  /* orientation-requested-default */
+  ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "orientation-requested-default", IPP_ORIENT_PORTRAIT);
+
+  /* orientation-requested-supported */
+  ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "orientation-requested-supported", (int)(sizeof(orientation_requested_supported) / sizeof(orientation_requested_supported[0])), orientation_requested_supported);
+
+  /* output-bin-default */
+  if (pc->num_bins > 0)
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "output-bin-default", NULL, pc->bins->pwg);
+  else
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "output-bin-default", NULL, "face-down");
+
+  /* output-bin-supported */
+  if (pc->num_bins > 0)
+  {
+    attr = ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "output-bin-supported", pc->num_bins, NULL,  NULL);
+    for (i = 0, pwg_map = pc->bins; i < pc->num_bins; i ++, pwg_map ++)
+      ippSetString(attrs, &attr, i, pwg_map->pwg);
+  }
+  else
+  {
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "output-bin-supported", NULL, "face-down");
+  }
+
+  /* overrides-supported */
+  ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "overrides-supported", (int)(sizeof(overrides_supported) / sizeof(overrides_supported[0])), NULL, overrides_supported);
+
+  /* page-ranges-supported */
+  ippAddBoolean(attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1);
+
+  /* pages-per-minute */
+  ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "pages-per-minute", ppd->throughput);
+
+  /* pages-per-minute-color */
+  if (ppd->color_device)
+    ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "pages-per-minute-color", ppd->throughput);
+
+  /* print-color-mode-default */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-color-mode-default", NULL, ppd->color_device ? "auto" : "monochrome");
+
+  /* print-color-mode-supported */
+  if (ppd->color_device)
+    ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-color-mode-supported", (int)(sizeof(print_color_mode_supported_color) / sizeof(print_color_mode_supported_color[0])), NULL, print_color_mode_supported_color);
+  else
+    ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-color-mode-supported", (int)(sizeof(print_color_mode_supported) / sizeof(print_color_mode_supported[0])), NULL, print_color_mode_supported);
+
+  /* print-content-optimize-default */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-content-optimize-default", NULL, "auto");
+
+  /* print-content-optimize-supported */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-content-optimize-supported", NULL, "auto");
+
+  /* print-quality-default */
+  ippAddInteger(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "print-quality-default", IPP_QUALITY_NORMAL);
+
+  /* print-quality-supported */
+  ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "print-quality-supported", (int)(sizeof(print_quality_supported) / sizeof(print_quality_supported[0])), print_quality_supported);
+
+  /* print-rendering-intent-default */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-rendering-intent-default", NULL, "auto");
+
+  /* print-rendering-intent-supported */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-rendering-intent-supported", NULL, "auto");
+
+  /* printer-device-id */
+  if ((ppd_attr = ppdFindAttr(ppd, "1284DeviceId", NULL)) != NULL)
+  {
+   /*
+    * Use the device ID string from the PPD...
+    */
+
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-device-id", NULL, ppd_attr->value);
+  }
+  else
+  {
+   /*
+    * Synthesize a device ID string...
+    */
+
+    char       device_id[1024];                /* Device ID string */
+
+    snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;CMD:PS;", ppd->manufacturer, ppd->modelname);
+
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-device-id", NULL, device_id);
+  }
+
+  /* printer-input-tray */
+  if (pc->num_sources > 0)
+  {
+    for (i = 0, attr = NULL; i < pc->num_sources; i ++)
+    {
+      char     input_tray[1024];       /* printer-input-tray value */
+
+      if (!strcmp(pc->sources[i].pwg, "manual") || strstr(pc->sources[i].pwg, "-man") != NULL)
+        snprintf(input_tray, sizeof(input_tray), "type=sheetFeedManual;mediafeed=0;mediaxfeed=0;maxcapacity=1;level=-2;status=0;name=%s", pc->sources[i].pwg);
+      else
+        snprintf(input_tray, sizeof(input_tray), "type=sheetFeedAutoRemovableTray;mediafeed=0;mediaxfeed=0;maxcapacity=250;level=125;status=0;name=%s", pc->sources[i].pwg);
+
+      if (attr)
+        ippSetOctetString(attrs, &attr, i, input_tray, (int)strlen(input_tray));
+      else
+        attr = ippAddOctetString(attrs, IPP_TAG_PRINTER, "printer-input-tray", input_tray, (int)strlen(input_tray));
+    }
+  }
+  else
+  {
+    static const char *printer_input_tray = "type=sheetFeedAutoRemovableTray;mediafeed=0;mediaxfeed=0;maxcapacity=-2;level=-2;status=0;name=auto";
+
+    ippAddOctetString(attrs, IPP_TAG_PRINTER, "printer-input-tray", printer_input_tray, (int)strlen(printer_input_tray));
+  }
+
+  /* printer-make-and-model */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-make-and-model", NULL, ppd->nickname);
+
+  /* printer-resolution-default */
+  ippAddResolution(attrs, IPP_TAG_PRINTER, "printer-resolution-default", IPP_RES_PER_INCH, xres, yres);
+
+  /* printer-resolution-supported */
+  ippAddResolution(attrs, IPP_TAG_PRINTER, "printer-resolution-supported", IPP_RES_PER_INCH, xres, yres);
+
+  /* printer-supply and printer-supply-description */
+  if (ppd->color_device)
+  {
+    attr = ippAddOctetString(attrs, IPP_TAG_PRINTER, "printer-supply", printer_supply_color[0], (int)strlen(printer_supply_color[0]));
+    for (i = 1; i < (int)(sizeof(printer_supply_color) / sizeof(printer_supply_color[0])); i ++)
+      ippSetOctetString(attrs, &attr, i, printer_supply_color[i], (int)strlen(printer_supply_color[i]));
+
+    ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_TEXT), "printer-supply-description", (int)(sizeof(printer_supply_description_color) / sizeof(printer_supply_description_color[0])), NULL, printer_supply_description_color);
+  }
+  else
+  {
+    attr = ippAddOctetString(attrs, IPP_TAG_PRINTER, "printer-supply", printer_supply[0], (int)strlen(printer_supply[0]));
+    for (i = 1; i < (int)(sizeof(printer_supply) / sizeof(printer_supply[0])); i ++)
+      ippSetOctetString(attrs, &attr, i, printer_supply[i], (int)strlen(printer_supply[i]));
+
+    ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_TEXT), "printer-supply-description", (int)(sizeof(printer_supply_description) / sizeof(printer_supply_description[0])), NULL, printer_supply_description);
+  }
+
+  /* pwg-raster-document-xxx-supported */
+  if (cupsArrayFind(docformats, (void *)"image/pwg-raster"))
+  {
+    ippAddResolution(attrs, IPP_TAG_PRINTER, "pwg-raster-document-resolution-supported", IPP_RES_PER_INCH, xres, yres);
+
+    if (pc->sides_2sided_long)
+      ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "pwg-raster-document-sheet-back", NULL, "normal");
+
+    if (ppd->color_device)
+      ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "pwg-raster-document-type-supported", (int)(sizeof(pwg_raster_document_type_supported_color) / sizeof(pwg_raster_document_type_supported_color[0])), NULL, pwg_raster_document_type_supported_color);
+    else
+      ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "pwg-raster-document-type-supported", (int)(sizeof(pwg_raster_document_type_supported) / sizeof(pwg_raster_document_type_supported[0])), NULL, pwg_raster_document_type_supported);
+  }
+
+  /* sides-default */
+  ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "sides-default", NULL, "one-sided");
+
+  /* sides-supported */
+  if (pc->sides_2sided_long)
+    ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "sides-supported", (int)(sizeof(sides_supported) / sizeof(sides_supported[0])), NULL, sides_supported);
+  else
+    ippAddString(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "sides-supported", NULL, "one-sided");
+
+  /* urf-supported */
+  if (cupsArrayFind(docformats, (void *)"image/urf"))
+    ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "urf-supported", num_urf, NULL, urf);
+
+ /*
+  * Free the PPD file and return the attributes...
+  */
+
+  ppdCacheDestroy(pc);
+
+  ppdClose(ppd);
+
+  return (attrs);
+}
+
+/*
+ * 'create_media_col()' - Create a media-col value.
+ */
+
+static ipp_t *                         /* O - media-col collection */
+create_media_col(const char *media,    /* I - Media name */
+                const char *source,    /* I - Media source, if any */
+                const char *type,      /* I - Media type, if any */
+                int        width,      /* I - x-dimension in 2540ths */
+                int        length,     /* I - y-dimension in 2540ths */
+                int        bottom,     /* I - Bottom margin in 2540ths */
+                int        left,       /* I - Left margin in 2540ths */
+                int        right,      /* I - Right margin in 2540ths */
+                int        top)        /* I - Top margin in 2540ths */
+{
+  ipp_t                *media_col = ippNew(),  /* media-col value */
+               *media_size = create_media_size(width, length);
+                                       /* media-size value */
+  char         media_key[256];         /* media-key value */
+  const char   *media_key_suffix = ""; /* media-key suffix */
+
+
+  if (bottom == 0 && left == 0 && right == 0 && top == 0)
+    media_key_suffix = "_borderless";
+
+  if (type && source)
+    snprintf(media_key, sizeof(media_key), "%s_%s_%s%s", media, source, type, media_key_suffix);
+  else if (type)
+    snprintf(media_key, sizeof(media_key), "%s__%s%s", media, type, media_key_suffix);
+  else if (source)
+    snprintf(media_key, sizeof(media_key), "%s_%s%s", media, source, media_key_suffix);
+  else
+    snprintf(media_key, sizeof(media_key), "%s%s", media, media_key_suffix);
+
+  ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-key", NULL, media_key);
+  ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size);
+  ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-size-name", NULL, media);
+  if (bottom >= 0)
+    ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin", bottom);
+  if (left >= 0)
+    ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin", left);
+  if (right >= 0)
+    ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin", right);
+  if (top >= 0)
+    ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin", top);
+  if (source)
+    ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-source", NULL, source);
+  if (type)
+    ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-type", NULL, type);
+
+  ippDelete(media_size);
+
+  return (media_col);
+}
+
+
+/*
+ * 'create_media_size()' - Create a media-size value.
+ */
+
+static ipp_t *                         /* O - media-col collection */
+create_media_size(int width,           /* I - x-dimension in 2540ths */
+                 int length)           /* I - y-dimension in 2540ths */
+{
+  ipp_t        *media_size = ippNew();         /* media-size value */
+
+
+  ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension", width);
+  ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension", length);
+
+  return (media_size);
+}
index 8b84cdb033ead6ca184dbf579cca8606fa34bb7f..b8004a45c90f676e422ed44dbbed4eb236e5f5cc 100644 (file)
--- a/ppd/ppd.h
+++ b/ppd/ppd.h
@@ -649,6 +649,10 @@ extern const char  *ppdPwgMediaTypeForType(const char *media_type,
 extern const char      *ppdPwgPageSizeForMedia(pwg_media_t *media,
                                              char *name, size_t namesize);
 
+/**** New in cups-filters 1.0.28: Overtaken from ippeveprinter ****/
+extern ipp_t           *ppdLoadAttributes(const char *ppdfile,
+                                          cups_array_t *docformats);
+
 
 /*
  * C++ magic...