From: msweet Date: Fri, 12 Jun 2015 01:21:05 +0000 (+0000) Subject: Bring back PWG white paper support for 3D print queues (just tagging of queues and... X-Git-Tag: v2.2b1~256 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a08320a77a5b1f99e8bda8ac53caaf1f017a7d3;p=thirdparty%2Fcups.git Bring back PWG white paper support for 3D print queues (just tagging of queues and drivers 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 --- diff --git a/CHANGES.txt b/CHANGES.txt index 113637de41..1ed8af5c0b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -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. diff --git a/conf/mime.types b/conf/mime.types index 002674e43a..68759232a5 100644 --- a/conf/mime.types +++ b/conf/mime.types @@ -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... diff --git a/cups/cups.h b/cups/cups.h index 2ccd85c81d..3b1111b8c0 100644 --- a/cups/cups.h +++ b/cups/cups.h @@ -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 | diff --git a/cups/dest.c b/cups/dest.c index 554903face..2affdb22cd 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -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) { diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index e8d9cc3770..0966f106f8 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -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. */ diff --git a/cups/ppd-private.h b/cups/ppd-private.h index 4360746ac0..34327027ab 100644 --- a/cups/ppd-private.h +++ b/cups/ppd-private.h @@ -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 */ }; diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx index 573d2e1e2f..73f3228d5f 100644 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@ -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 */ @@ -42,9 +42,12 @@ #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); diff --git a/scheduler/printers.c b/scheduler/printers.c index 86b3e5939c..c80a0c6c18 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -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... */