From ab8fab6154417d737ff4912cdd409c9dcab285af Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Mon, 22 Apr 2019 18:27:46 -0400 Subject: [PATCH] Save work on PPD support. --- test/ippeveprinter.c | 631 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 610 insertions(+), 21 deletions(-) diff --git a/test/ippeveprinter.c b/test/ippeveprinter.c index ba7aea0dc..9d00f8d26 100644 --- a/test/ippeveprinter.c +++ b/test/ippeveprinter.c @@ -570,9 +570,6 @@ main(int argc, /* I - Number of command-line args */ * Apply defaults as needed... */ - if (!docformats) - docformats = _cupsArrayNewStrings("application/pdf,image/jpeg,image/pwg-raster", ','); - if (!serverport) { #ifdef _WIN32 @@ -636,13 +633,18 @@ main(int argc, /* I - Number of command-line args */ */ if (!docformats) - docformats = _cupsArrayNewStrings("image/pwg-raster", ','); + docformats = _cupsArrayNewStrings(ppm_color > 0 ? "image/jpeg,image/pwg-raster,image/urf": "image/pwg-raster,image/urf", ','); if (attrfile) attrs = load_ippserver_attributes(servername, serverport, attrfile, docformats); #if !CUPS_LITE else if (ppdfile) + { attrs = load_ppd_attributes(ppdfile, docformats); + + if (!command) + command = "ippeveps"; + } #endif /* !CUPS_LITE */ else attrs = load_legacy_attributes(make, model, ppm, ppm_color, duplex, docformats); @@ -4501,38 +4503,625 @@ load_ppd_attributes( const char *ppdfile, /* I - PPD filename */ cups_array_t *docformats) /* I - document-format-supported values */ { - (void)ppdfile; - (void)docformats; - -#if 0 - static const char * const overrides[] = + 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_size_t *ppd_size; /* Default PPD size */ + pwg_size_t *pwg_size, /* Current PWG size */ + *default_size = NULL; /* Default PWG size */ + pwg_map_t *pwg_map; /* Mapping from PWG to PPD keywords */ + _ppd_cache_t *pc; /* PPD cache */ + _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-number", + "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); + _cupsLangPrintf(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_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... + */ + + cupsArrayAdd(docformats, "application/pdf"); + + /* + * 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 */ - if (!ippFindAttribute(printer->attrs, "document-password-supported", IPP_TAG_ZERO)) - ippAddInteger(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "document-password-supported", 127); + 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 = (_pwg_finishings_t *)cupsArrayFirst(pc->finishings); finishings; i ++, finishings = (_pwg_finishings_t *)cupsArrayNext(pc->finishings)) + ippSetInteger(attrs, &attr, i, 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 = (_pwg_finishings_t *)cupsArrayFirst(pc->finishings); finishings; i ++, finishings = (_pwg_finishings_t *)cupsArrayNext(pc->finishings)) + ippSetInteger(attrs, &attr, i, 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, NULL, NULL, 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, pc->num_sources > 0 ? pc->sources[0].pwg : NULL, pc->num_types > 0 ? pc->types[0].pwg : NULL, 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 */ - if (!ippFindAttribute(printer->attrs, "overrides-supported", IPP_TAG_ZERO)) - ippAddStrings(printer->attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "overrides-supported", (int)(sizeof(overrides) / sizeof(overrides[0])), NULL, overrides); + 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 */ - if (!ippFindAttribute(printer->attrs, "page-ranges-supported", IPP_TAG_ZERO)) - ippAddBoolean(printer->attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1); + ippAddBoolean(attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1); + /* pages-per-minute */ - ippAddInteger(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "pages-per-minute", ppm); + 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 0 if (ppm_color > 0) - ippAddInteger(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "pages-per-minute-color", ppm_color); + { + attr = ippAddOctetString(attrs, IPP_TAG_PRINTER, "printer-input-tray", printer_input_tray_color[0], strlen(printer_input_tray_color[0])); + for (i = 1; i < (int)(sizeof(printer_input_tray_color) / sizeof(printer_input_tray_color[0])); i ++) + ippSetOctetString(attrs, &attr, i, printer_input_tray_color[i], strlen(printer_input_tray_color[i])); + } + else + { + attr = ippAddOctetString(attrs, IPP_TAG_PRINTER, "printer-input-tray", printer_input_tray[0], strlen(printer_input_tray[0])); + for (i = 1; i < (int)(sizeof(printer_input_tray) / sizeof(printer_input_tray[0])); i ++) + ippSetOctetString(attrs, &attr, i, printer_input_tray[i], strlen(printer_input_tray[i])); + } #endif /* 0 */ - return (NULL); + /* 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], 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], 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], strlen(printer_supply[0])); + for (i = 1; i < (int)(sizeof(printer_supply) / sizeof(printer_supply[0])); i ++) + ippSetOctetString(attrs, &attr, i, printer_supply[i], 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); } #endif /* !CUPS_LITE */ -- 2.39.2