]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Bring back PWG white paper support for 3D print queues (just tagging of queues and...
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Fri, 12 Jun 2015 01:21:05 +0000 (01:21 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Fri, 12 Jun 2015 01:21:05 +0000 (01:21 +0000)
that are 3D-specific, with 3D queues omitted from 2D print dialogs)

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12733 a1ca3aef-8c08-0410-bb20-df032aa958be

CHANGES.txt
conf/mime.types
cups/cups.h
cups/dest.c
cups/ppd-cache.c
cups/ppd-private.h
scheduler/cups-driverd.cxx
scheduler/printers.c

index 113637de41fc4f53e811f186d54c939ae564f631..1ed8af5c0bc8be0eda8a1722eb01d2bce9f13d43 100644 (file)
@@ -39,4 +39,6 @@ CHANGES IN CUPS V2.1b1
          "syslog" output is configured (STR #4474)
        - The scheduler now supports logging to stderr when running in the
          foreground (STR #4505)
+       - Added support for 3D printers (basic types only, no built-in filters)
+         based on PWG white paper.
 
index 002674e43a11aa99fcfb9969aa1d2b387abfc2a5..68759232a53a6a2fa15363159fb6c39b10cdd38d 100644 (file)
@@ -7,7 +7,7 @@
 # VERSIONS OF CUPS.  Instead, create a "local.types" file that
 # reflects your local configuration changes.
 #
-# Copyright 2007-2014 by Apple Inc.
+# Copyright 2007-2015 by Apple Inc.
 # Copyright 1997-2007 by Easy Software Products.
 #
 # These coded instructions, statements, and computer programs are the
@@ -81,6 +81,13 @@ application/postscript               ai eps ps string(0,%!) string(0,<04>%!) \
                                 (contains(0,4096,<0a>%!) + \
                                  !contains(0,4096,"ENTER LANGUAGE")))
 
+application/g-code             gcode
+application/sla                        stl string(0,"solid ") + contains(0,4096,"facet") + contains(0,4096,"vertex")
+application/vnd.makerbot-s3g   x3g
+model/amf                      amf
+model/vnd.collada+xml          dae
+
+
 ########################################################################
 #
 # Image files...
index 2ccd85c81d08addb1b1415701e8457df9bef6d1e..3b1111b8c0044eb2994f99b9be158d766d0b0820 100644 (file)
@@ -250,6 +250,7 @@ enum cups_ptype_e                   /* Printer type/capability bit
                                         * @since CUPS 1.4/OS X 10.6@ */
   CUPS_PRINTER_MFP = 0x4000000,                /* Printer with scanning capabilities
                                         * @since CUPS 1.4/OS X 10.6@ */
+  CUPS_PRINTER_3D = 0x8000000,         /* 3D Printing @since CUPS 2.1@ */
   CUPS_PRINTER_OPTIONS = 0x6fffc       /* ~(CLASS | REMOTE | IMPLICIT |
                                         * DEFAULT | FAX | REJECTING | DELETE |
                                         * NOT_SHARED | AUTHENTICATED |
index 554903facef52d1fba2f98db862b888c54b5e089..2affdb22cd57b3152a5d67d1396efd3fd335857c 100644 (file)
@@ -871,7 +871,7 @@ cupsEnumDests(
   */
 
   num_dests = _cupsGetDests(CUPS_HTTP_DEFAULT, IPP_OP_CUPS_GET_PRINTERS, NULL,
-                            &dests, type, mask);
+                            &dests, type, mask | CUPS_PRINTER_3D);
 
   if ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL)
     defprinter = name;
@@ -1743,7 +1743,7 @@ cupsGetDests2(http_t      *http,  /* I - Connection to server or @code CUPS_HTTP_
   */
 
   *dests    = (cups_dest_t *)0;
-  num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, dests, 0, 0);
+  num_dests = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, dests, 0, CUPS_PRINTER_3D);
 
   if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE)
   {
@@ -1960,7 +1960,7 @@ cupsGetNamedDest(http_t     *http,        /* I - Connection to server or @code CUPS_HTT
   * Get the printer's attributes...
   */
 
-  if (!_cupsGetDests(http, op, name, &dest, 0, 0))
+  if (!_cupsGetDests(http, op, name, &dest, 0, CUPS_PRINTER_3D))
     return (NULL);
 
   if (instance)
@@ -2136,7 +2136,7 @@ cupsSetDests2(http_t      *http,  /* I - Connection to server or @code CUPS_HTTP_
   * Get the server destinations...
   */
 
-  num_temps = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &temps, 0, 0);
+  num_temps = _cupsGetDests(http, IPP_OP_CUPS_GET_PRINTERS, NULL, &temps, 0, CUPS_PRINTER_3D);
 
   if (cupsLastError() >= IPP_STATUS_REDIRECTION_OTHER_SITE)
   {
index e8d9cc37703d8348bd94939c109a64cd1426ff72..0966f106f8862d3c4e86445b8a4a1e7050c9c28f 100644 (file)
@@ -36,6 +36,7 @@
 static int     pwg_compare_finishings(_pwg_finishings_t *a,
                                       _pwg_finishings_t *b);
 static void    pwg_free_finishings(_pwg_finishings_t *f);
+static void    pwg_free_material(_pwg_material_t *m);
 static void    pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
 static void    pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize);
 static void    pwg_unppdize_name(const char *ppd, char *name, size_t namesize,
@@ -480,6 +481,53 @@ _ppdCacheCreateWithFile(
       _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad PPD cache file."), 1);
       goto create_error;
     }
+    else if (!_cups_strcasecmp(line, "3D"))
+    {
+      pc->cups_3d = _cupsStrAlloc(value);
+    }
+    else if (!_cups_strcasecmp(line, "LayerOrder"))
+    {
+      pc->cups_layer_order = _cupsStrAlloc(value);
+    }
+    else if (!_cups_strcasecmp(line, "Accuracy"))
+    {
+      sscanf(value, "%d%d%d", pc->cups_accuracy + 0, pc->cups_accuracy + 1, pc->cups_accuracy + 2);
+    }
+    else if (!_cups_strcasecmp(line, "Volume"))
+    {
+      sscanf(value, "%d%d%d", pc->cups_volume + 0, pc->cups_volume + 1, pc->cups_volume + 2);
+    }
+    else if (!_cups_strcasecmp(line, "Material"))
+    {
+     /*
+      * Material key "name" name=value ... name=value
+      */
+
+      if ((valueptr = strchr(value, ' ')) != NULL)
+      {
+       _pwg_material_t *material = (_pwg_material_t *)calloc(1, sizeof(_pwg_material_t));
+
+        *valueptr++ = '\0';
+
+        material->key = _cupsStrAlloc(value);
+
+        if (*valueptr == '\"')
+       {
+         value = valueptr + 1;
+         if ((valueptr = strchr(value, '\"')) != NULL)
+         {
+           *valueptr++ = '\0';
+           material->name = _cupsStrAlloc(value);
+           material->num_props = cupsParseOptions(valueptr, 0, &material->props);
+         }
+       }
+
+       if (!pc->materials)
+         pc->materials = cupsArrayNew3(NULL, NULL, NULL, 0, NULL, (cups_afree_func_t)pwg_free_material);
+
+        cupsArrayAdd(pc->materials, material);
+      }
+    }
     else if (!_cups_strcasecmp(line, "Filter"))
     {
       if (!pc->filters)
@@ -1711,6 +1759,42 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd)  /* I - PPD file */
   if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL)
     cupsArrayAdd(pc->support_files, ppd_attr->value);
 
+ /*
+  * 3D stuff...
+  */
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cups3D", NULL)) != NULL)
+    pc->cups_3d = _cupsStrAlloc(ppd_attr->value);
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsLayerOrder", NULL)) != NULL)
+    pc->cups_layer_order = _cupsStrAlloc(ppd_attr->value);
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsAccuracy", NULL)) != NULL)
+    sscanf(ppd_attr->value, "%d%d%d", pc->cups_accuracy + 0, pc->cups_accuracy + 1, pc->cups_accuracy + 2);
+
+  if ((ppd_attr = ppdFindAttr(ppd, "cupsVolume", NULL)) != NULL)
+    sscanf(ppd_attr->value, "%d%d%d", pc->cups_volume + 0, pc->cups_volume + 1, pc->cups_volume + 2);
+
+  for (ppd_attr = ppdFindAttr(ppd, "cupsMaterial", NULL);
+       ppd_attr;
+       ppd_attr = ppdFindNextAttr(ppd, "cupsMaterial", NULL))
+  {
+   /*
+    * *cupsMaterial key/name: "name=value ... name=value"
+    */
+
+    _pwg_material_t    *material = (_pwg_material_t *)calloc(1, sizeof(_pwg_material_t));
+
+    material->key = _cupsStrAlloc(ppd_attr->name);
+    material->name = _cupsStrAlloc(ppd_attr->text);
+    material->num_props = cupsParseOptions(ppd_attr->value, 0, &material->props);
+
+    if (!pc->materials)
+      pc->materials = cupsArrayNew3(NULL, NULL, NULL, 0, NULL, (cups_afree_func_t)pwg_free_material);
+
+    cupsArrayAdd(pc->materials, material);
+  }
+
  /*
   * Return the cache data...
   */
@@ -1818,6 +1902,11 @@ _ppdCacheDestroy(_ppd_cache_t *pc)       /* I - PPD cache and mapping data */
 
   cupsArrayDelete(pc->support_files);
 
+  _cupsStrFree(pc->cups_3d);
+  _cupsStrFree(pc->cups_layer_order);
+
+  cupsArrayDelete(pc->materials);
+
   free(pc);
 }
 
@@ -2575,6 +2664,7 @@ _ppdCacheWriteFile(
   cups_option_t                *option;        /* Current option */
   const char           *value;         /* Filter/pre-filter value */
   char                 newfile[1024];  /* New filename */
+  _pwg_material_t      *m;             /* Material */
 
 
  /*
@@ -2755,6 +2845,32 @@ _ppdCacheWriteFile(
        value = (char *)cupsArrayNext(pc->support_files))
     cupsFilePutConf(fp, "SupportFile", value);
 
+ /*
+  * 3D stuff...
+  */
+
+  if (pc->cups_3d)
+    cupsFilePutConf(fp, "3D", pc->cups_3d);
+
+  if (pc->cups_layer_order)
+    cupsFilePutConf(fp, "LayerOrder", pc->cups_layer_order);
+
+  if (pc->cups_accuracy[0] || pc->cups_accuracy[0] || pc->cups_accuracy[2])
+    cupsFilePrintf(fp, "Accuracy %d %d %d\n", pc->cups_accuracy[0], pc->cups_accuracy[1], pc->cups_accuracy[2]);
+
+  if (pc->cups_volume[0] || pc->cups_volume[0] || pc->cups_volume[2])
+    cupsFilePrintf(fp, "Volume %d %d %d\n", pc->cups_volume[0], pc->cups_volume[1], pc->cups_volume[2]);
+
+  for (m = (_pwg_material_t *)cupsArrayFirst(pc->materials);
+       m;
+       m = (_pwg_material_t *)cupsArrayNext(pc->materials))
+  {
+    cupsFilePrintf(fp, "Material %s \"%s\"", m->key, m->name);
+    for (i = 0; i < m->num_props; i ++)
+      cupsFilePrintf(fp, " %s=%s", m->props[i].name, m->props[i].value);
+    cupsFilePuts(fp, "\n");
+  }
+
  /*
   * IPP attributes, if any...
   */
@@ -3561,6 +3677,22 @@ pwg_free_finishings(
 }
 
 
+/*
+ * 'pwg_free_material()' - Free a material value.
+ */
+
+static void
+pwg_free_material(_pwg_material_t *m)  /* I - Material value */
+{
+  _cupsStrFree(m->key);
+  _cupsStrFree(m->name);
+
+  cupsFreeOptions(m->num_props, m->props);
+
+  free(m);
+}
+
+
 /*
  * 'pwg_ppdize_name()' - Convert an IPP keyword to a PPD keyword.
  */
@@ -3591,7 +3723,6 @@ pwg_ppdize_name(const char *ipp,  /* I - IPP keyword */
 }
 
 
-
 /*
  * 'pwg_ppdize_resolution()' - Convert PWG resolution values to PPD values.
  */
index 4360746ac0e207aab444605c479f2c494aa727d2..34327027ab7245cdfb0ea34262b1180e46828f78 100644 (file)
@@ -109,6 +109,14 @@ typedef struct _pwg_finishings_s   /**** PWG finishings mapping data ****/
   cups_option_t                *options;       /* Options to apply */
 } _pwg_finishings_t;
 
+typedef struct _pwg_material_s         /**** PWG material mapping data ****/
+{
+  char         *key,                   /* material-key value */
+               *name;                  /* material-name value */
+  int          num_props;              /* Number of properties */
+  cups_option_t        *props;                 /* Material properties */
+} _pwg_material_t;
+
 struct _ppd_cache_s                    /**** PPD cache and PWG conversion data ****/
 {
   int          num_bins;               /* Number of output bins */
@@ -148,6 +156,11 @@ struct _ppd_cache_s                        /**** PPD cache and PWG conversion data ****/
   cups_array_t *mandatory;             /* cupsMandatory value */
   char         *charge_info_uri;       /* cupsChargeInfoURI value */
   cups_array_t *support_files;         /* Support files - ICC profiles, etc. */
+  char         *cups_3d,               /* cups3D value */
+               *cups_layer_order;      /* cupsLayerOrder value */
+  int          cups_accuracy[3];       /* cupsAccuracy value - x, y, and z in nanometers */
+  int          cups_volume[3];         /* cupsVolume value - x, y, and z in millimeters */
+  cups_array_t *materials;             /* cupsMaterial values */
 };
 
 
index 573d2e1e2fa9a66afe43356cde1f0df58a6a74bc..73f3228d5fb3ee576b2745333abf60a2037c63a3 100644 (file)
@@ -33,7 +33,7 @@
  * Constants...
  */
 
-#define PPD_SYNC       0x50504437      /* Sync word for ppds.dat (PPD7) */
+#define PPD_SYNC       0x50504438      /* Sync word for ppds.dat (PPD8) */
 #define PPD_MAX_LANG   32              /* Maximum languages */
 #define PPD_MAX_PROD   32              /* Maximum products */
 #define PPD_MAX_VERS   32              /* Maximum versions */
 #define PPD_TYPE_PDF           1       /* PDF PPD */
 #define PPD_TYPE_RASTER                2       /* CUPS raster PPD */
 #define PPD_TYPE_FAX           3       /* Facsimile/MFD PPD */
-#define PPD_TYPE_UNKNOWN       4       /* Other/hybrid PPD */
-#define PPD_TYPE_DRV           5       /* Driver info file */
-#define PPD_TYPE_ARCHIVE       6       /* Archive file */
+#define PPD_TYPE_OBJECT_ANY    4       /* 3D (AMF/STL/g-code) PPD */
+#define PPD_TYPE_OBJECT_DIRECT 5       /* 3D (AMF/STL/g-code) PPD over any connection */
+#define PPD_TYPE_OBJECT_STORAGE        6       /* 3D (AMF/STL/g-code) PPD for storage to SD card, etc. */
+#define PPD_TYPE_UNKNOWN       7       /* Other/hybrid PPD */
+#define PPD_TYPE_DRV           8       /* Driver info file */
+#define PPD_TYPE_ARCHIVE       9       /* Archive file */
 
 #define TAR_BLOCK      512             /* Number of bytes in a block */
 #define TAR_BLOCKS     10              /* Blocking factor */
@@ -135,6 +138,9 @@ static const char * const PPDTypes[] =      /* ppd-type values */
                          "pdf",
                          "raster",
                          "fax",
+                         "object",
+                         "object-direct",
+                         "object-storage",
                          "unknown",
                          "drv",
                          "archive"
@@ -1172,11 +1178,11 @@ list_ppds(int        request_id,        /* I - Request ID */
   load_drivers(include, exclude);
 
  /*
-  * Add the raw and IPP Everywhere drivers...
+  * Add the raw driver...
   */
 
-  add_ppd("", "everywhere", "en", "Generic", "IPP Everywhere", "", "", "", 0, 0, 0, PPD_TYPE_UNKNOWN, "everywhere");
-  add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0, PPD_TYPE_UNKNOWN, "raw");
+  add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0,
+          PPD_TYPE_UNKNOWN, "raw");
 
  /*
   * Send IPP attributes...
@@ -2095,12 +2101,28 @@ load_ppd(const char  *filename,         /* I - Real filename */
       if (!_cups_strncasecmp(ptr, "true", 4))
        type = PPD_TYPE_FAX;
     }
-    else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT)
+    else if ((!strncmp(line, "*cupsFilter:", 12) || !strncmp(line, "*cupsFilter2:", 13)) && type == PPD_TYPE_POSTSCRIPT)
     {
       if (strstr(line + 12, "application/vnd.cups-raster"))
        type = PPD_TYPE_RASTER;
       else if (strstr(line + 12, "application/vnd.cups-pdf"))
        type = PPD_TYPE_PDF;
+      else if (strstr(line + 12, "application/amf") ||
+               strstr(line + 12, "application/g-code") ||
+               strstr(line + 12, "application/sla"))
+       type = PPD_TYPE_OBJECT_ANY;
+    }
+    else if (!strncmp(line, "*cups3DWorkflows:", 17))
+    {
+      int is_direct = strstr(line + 17, "direct") != NULL;
+      int is_storage = strstr(line + 17, "storage") != NULL;
+
+      if (is_direct && !is_storage)
+        type = PPD_TYPE_OBJECT_DIRECT;
+      if (!is_direct && is_storage)
+        type = PPD_TYPE_OBJECT_STORAGE;
+      else
+        type = PPD_TYPE_OBJECT_ANY;
     }
     else if (!strncmp(line, "*cupsModelNumber:", 17))
       sscanf(line, "*cupsModelNumber:%d", &model_number);
index 86b3e5939cb06e2aca715aa83d6467099759605f..c80a0c6c180523e74fb90d7b48cae2b8fdee9b8c 100644 (file)
@@ -3990,10 +3990,10 @@ load_ppd(cupsd_printer_t *p)            /* I - Printer */
 
     if (ppd->num_sizes == 0 || !p->pc)
     {
-      if (!ppdFindAttr(ppd, "APScannerOnly", NULL))
+      if (!ppdFindAttr(ppd, "APScannerOnly", NULL) && !ppdFindAttr(ppd, "cups3D", NULL))
        cupsdLogMessage(CUPSD_LOG_CRIT,
                        "The PPD file for printer %s contains no media "
-                       "options and is therefore invalid!", p->name);
+                       "options and is therefore invalid.", p->name);
 
       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
                   "media-default", NULL, "unknown");
@@ -4682,6 +4682,13 @@ load_ppd(cupsd_printer_t *p)             /* I - Printer */
                   "printer-commands", NULL, "none");
     }
 
+   /*
+    * 3D printer support...
+    */
+
+    if (ppdFindAttr(ppd, "cups3D", NULL))
+      p->type |= CUPS_PRINTER_3D;
+
    /*
     * Show current and available port monitors for this printer...
     */