From: Michael R Sweet Date: Tue, 9 Apr 2024 22:18:32 +0000 (-0400) Subject: Initial work on loading all desired languages from IPP printer. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ecce59a05a4f43fac8e57dbf53fd2c18df5e02e;p=thirdparty%2Fcups.git Initial work on loading all desired languages from IPP printer. --- diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index 34b11304e8..ae88076cfb 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -30,8 +30,11 @@ */ static int cups_connect(http_t **http, const char *url, char *resource, size_t ressize); -static int cups_get_url(http_t **http, const char *url, char *name, size_t namesize); +static cups_array_t *cups_get_languages(void); +static cups_lang_t *cups_get_strings(http_t **http, const char *printer_uri, const char *language); +static int cups_get_url(http_t **http, const char *url, const char *suffix, char *name, size_t namesize); static const char *ppd_inputslot_for_keyword(_ppd_cache_t *pc, const char *keyword); +static void ppd_put_strings(cups_file_t *fp, cups_lang_t *langs, const char *ppd_option, const char *ppd_choice, const char *pwg_msgid); static void pwg_add_finishing(cups_array_t *finishings, ipp_finishings_t template, const char *name, const char *value); static void pwg_add_message(cups_array_t *a, const char *msg, const char *str); static int pwg_compare_finishings(_pwg_finishings_t *a, _pwg_finishings_t *b, void *data); @@ -3131,28 +3134,17 @@ _ppdCacheWriteFile( * of an IPP printer. */ -char * /* O - PPD filename or @code NULL@ on error */ +char * /* O - PPD filename or `NULL` on error */ _ppdCreateFromIPP(char *buffer, /* I - Filename buffer */ size_t bufsize, /* I - Size of filename buffer */ ipp_t *supported) /* I - Get-Printer-Attributes response */ { - return (_ppdCreateFromIPP2(buffer, bufsize, supported, cupsLangDefault())); -} - - -/* - * '_ppdCreateFromIPP2()' - Create a PPD file describing the capabilities - * of an IPP printer. - */ - - -char * -_ppdCreateFromIPP2( - char *buffer, /* I - Filename buffer */ - size_t bufsize, /* I - Size of filename buffer */ - ipp_t *supported, /* I - Get-Printer-Attributes response */ - cups_lang_t *lang) /* I - Language */ -{ + const char *printer_uri; /* Printer URI */ + http_t *http = NULL; /* HTTP connection */ + cups_array_t *languages; /* List of languages */ + cups_lang_t *lang, /* Current language information */ + *langs = NULL; /* Language (strings) files */ + const char *prefix; /* Prefix string */ cups_file_t *fp; /* PPD file */ cups_array_t *sizes; /* Media sizes supported by printer */ cups_size_t *size; /* Current media size */ @@ -3187,10 +3179,8 @@ _ppdCreateFromIPP2( /* Array of resolution indices */ int have_qdraft = 0,/* Have draft quality? */ have_qhigh = 0; /* Have high quality? */ - char msgid[256]; /* Message identifier (attr.value) */ - const char *keyword, /* Keyword value */ - *msgstr; /* Localized string */ - cups_array_t *strings = NULL;/* Printer strings file */ + char msgid[256]; /* PWG message identifier (attr.value) */ + const char *keyword; /* Keyword value */ struct lconv *loc = localeconv(); /* Locale data */ cups_array_t *fin_options = NULL; @@ -3216,16 +3206,28 @@ _ppdCreateFromIPP2( return (NULL); } + if ((printer_uri = ippGetString(ippFindAttribute(supported, "printer-uri-supported", IPP_TAG_URI), 0, NULL)) == NULL) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("No printer-uri-supported attribute."), 1); + return (NULL); + } + /* * Open a temporary file for the PPD... */ - if ((fp = cupsTempFile2(buffer, (int)bufsize)) == NULL) + if ((fp = cupsCreateTempFile("ippeve", ".ppd", buffer, bufsize)) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0); return (NULL); } + /* + * Figure out the languages to load/generate... + */ + + languages = cups_get_languages(); + /* * Standard stuff for PPD file... */ @@ -3261,7 +3263,7 @@ _ppdCreateFromIPP2( cupsFilePrintf(fp, "*NickName: \"%s - IPP Everywhere\"\n", model); cupsFilePrintf(fp, "*ShortNickName: \"%s - IPP Everywhere\"\n", model); - if ((attr = ippFindAttribute(supported, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0)) + if (ippGetBoolean(ippFindAttribute(supported, "color-supported", IPP_TAG_BOOLEAN), 0)) cupsFilePuts(fp, "*ColorDevice: True\n"); else cupsFilePuts(fp, "*ColorDevice: False\n"); @@ -3271,81 +3273,47 @@ _ppdCreateFromIPP2( cupsFilePrintf(fp, "*APAirPrint: True\n"); #endif // __APPLE__ cupsFilePuts(fp, "*cupsSNMPSupplies: False\n"); - cupsFilePrintf(fp, "*cupsLanguages: \"%s", lang->language); - if ((lang_supp = ippFindAttribute(supported, "printer-strings-languages-supported", IPP_TAG_LANGUAGE)) != NULL) - { - for (i = 0, count = ippGetCount(lang_supp); i < count; i ++) - { - keyword = ippGetString(lang_supp, i, NULL); - if (strcmp(keyword, lang->language)) - cupsFilePrintf(fp, " %s", keyword); - } - } - cupsFilePuts(fp, "\"\n"); - - if ((attr = ippFindAttribute(supported, "printer-more-info", IPP_TAG_URI)) != NULL) - cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL)); - - if ((attr = ippFindAttribute(supported, "printer-charge-info-uri", IPP_TAG_URI)) != NULL) - cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL)); - - if ((attr = ippFindAttribute(supported, "printer-strings-uri", IPP_TAG_URI)) != NULL) + if ((lang_supp = ippFindAttribute(supported, "printer-strings-languages-supported", IPP_TAG_LANGUAGE)) != NULL) { - http_t *http = NULL; /* Connection to printer */ - char stringsfile[1024]; /* Temporary strings file */ + /* + * List supported languages... + */ - if (cups_get_url(&http, ippGetString(attr, 0, NULL), stringsfile, sizeof(stringsfile))) + for (i = 0, count = ippGetCount(lang_supp), prefix = "*cupsLanguages: \""; i < count; i ++) { - const char *printer_uri = ippGetString(ippFindAttribute(supported, "printer-uri-supported", IPP_TAG_URI), 0, NULL); - // Printer URI - char resource[256]; // Resource path - ipp_t *request, // Get-Printer-Attributes request - *response; // Response to request - - /* - * Load strings and save the URL for clients using the destination API - * instead of this PPD file... - */ - - cupsFilePrintf(fp, "*cupsStringsURI: \"%s\"\n", ippGetString(attr, 0, NULL)); - - strings = _cupsMessageLoad(stringsfile, _CUPS_MESSAGE_STRINGS | _CUPS_MESSAGE_UNQUOTE); - - unlink(stringsfile); + keyword = ippGetString(lang_supp, i, NULL); - if (lang_supp && printer_uri && cups_connect(&http, printer_uri, resource, sizeof(resource))) + if (cupsArrayFind(languages, (void *)keyword) && (lang = cups_get_strings(&http, printer_uri, keyword)) != NULL) { /* - * Loop through all of the languages and save their URIs... - */ + * Add language... + */ - for (i = 0, count = ippGetCount(lang_supp); i < count; i ++) - { - keyword = ippGetString(lang_supp, i, NULL); + lang->next = langs; + langs = lang; - request = ippNew(); - ippSetOperation(request, IPP_OP_GET_PRINTER_ATTRIBUTES); - ippSetRequestId(request, i + 1); - ippAddString(request, IPP_TAG_OPERATION, IPP_CONST_TAG(IPP_TAG_CHARSET), "attributes-charset", NULL, "utf-8"); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, keyword); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); - ippAddString(request, IPP_TAG_OPERATION, IPP_CONST_TAG(IPP_TAG_KEYWORD), "requested-attributes", NULL, "printer-strings-uri"); - - response = cupsDoRequest(http, request, resource); - - if ((attr = ippFindAttribute(response, "printer-strings-uri", IPP_TAG_URI)) != NULL) - cupsFilePrintf(fp, "*cupsStringsURI %s: \"%s\"\n", keyword, ippGetString(attr, 0, NULL)); - - ippDelete(response); - } + cupsFilePrintf(fp, "%s%s", prefix, keyword); + prefix = ","; } } - if (http) - httpClose(http); + if (!strcmp(prefix, ",")) + cupsFilePuts(fp, "\"\n"); + } + + if (http) + { + httpClose(http); + http = NULL; } + if ((attr = ippFindAttribute(supported, "printer-more-info", IPP_TAG_URI)) != NULL) + cupsFilePrintf(fp, "*APSupplies: \"%s\"\n", ippGetString(attr, 0, NULL)); + + if ((attr = ippFindAttribute(supported, "printer-charge-info-uri", IPP_TAG_URI)) != NULL) + cupsFilePrintf(fp, "*cupsChargeInfoURI: \"%s\"\n", ippGetString(attr, 0, NULL)); + /* * Accounting... */ @@ -3361,38 +3329,36 @@ _ppdCreateFromIPP2( if ((attr = ippFindAttribute(supported, "printer-mandatory-job-attributes", IPP_TAG_KEYWORD)) != NULL) { - char prefix = '\"'; // Prefix for string - - cupsFilePuts(fp, "*cupsMandatory: \""); - for (i = 0, count = ippGetCount(attr); i < count; i ++) + for (i = 0, count = ippGetCount(attr), prefix = "*cupsMandatory: \""; i < count; i ++) { keyword = ippGetString(attr, i, NULL); if (strcmp(keyword, "attributes-charset") && strcmp(keyword, "attributes-natural-language") && strcmp(keyword, "printer-uri")) { - cupsFilePrintf(fp, "%c%s", prefix, keyword); - prefix = ','; + cupsFilePrintf(fp, "%s%s", prefix, keyword); + prefix = ","; } } - cupsFilePuts(fp, "\"\n"); + + if (!strcmp(prefix, ",")) + cupsFilePuts(fp, "\"\n"); } if ((attr = ippFindAttribute(supported, "printer-requested-job-attributes", IPP_TAG_KEYWORD)) != NULL) { - char prefix = '\"'; // Prefix for string - - cupsFilePuts(fp, "*cupsRequested: \""); - for (i = 0, count = ippGetCount(attr); i < count; i ++) + for (i = 0, count = ippGetCount(attr), prefix = "*cupsRequested: \""; i < count; i ++) { keyword = ippGetString(attr, i, NULL); if (strcmp(keyword, "attributes-charset") && strcmp(keyword, "attributes-natural-language") && strcmp(keyword, "printer-uri")) { - cupsFilePrintf(fp, "%c%s", prefix, keyword); - prefix = ','; + cupsFilePrintf(fp, "%s%s", prefix, keyword); + prefix = ","; } } - cupsFilePuts(fp, "\"\n"); + + if (!strcmp(prefix, ",")) + cupsFilePuts(fp, "\"\n"); } /* @@ -3926,18 +3892,16 @@ _ppdCreateFromIPP2( cupsFilePrintf(fp, "*DefaultInputSlot: %s\n", ppdname); for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++) + { if (!strcmp(sources[j], keyword)) { snprintf(msgid, sizeof(msgid), "media-source.%s", keyword); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; - cupsFilePrintf(fp, "*InputSlot %s: \"<>setpagedevice\"\n", ppdname, j); - cupsFilePrintf(fp, "*%s.InputSlot %s/%s: \"\"\n", lang->language, ppdname, msgstr); + ppd_put_strings(fp, langs, "InputSlot", ppdname, msgid); break; } + } } cupsFilePuts(fp, "*CloseUI: *InputSlot\n"); } @@ -3963,12 +3927,9 @@ _ppdCreateFromIPP2( pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); snprintf(msgid, sizeof(msgid), "media-type.%s", keyword); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; - cupsFilePrintf(fp, "*MediaType %s: \"<>setpagedevice\"\n", ppdname, ppdname); - cupsFilePrintf(fp, "*%s.MediaType %s/%s: \"\"\n", lang->language, ppdname, msgstr); + cupsFilePrintf(fp, "*MediaType %s: \"<>setpagedevice\"\n", ppdname, keyword); + ppd_put_strings(fp, langs, "MediaType", ppdname, msgid); } cupsFilePuts(fp, "*CloseUI: *MediaType\n"); } @@ -4015,26 +3976,25 @@ _ppdCreateFromIPP2( cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi); - cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n" - "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" - "*%s.Translation cupsPrintQuality/%s: \"\"\n" - "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality"))); + cupsFilePuts(fp, "*OpenUI *cupsPrintQuality: PickOne\n" + "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" + "*DefaultcupsPrintQuality: Normal\n"); if ((lowdpi & 1) == 0) { - cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi / 2, lang->language, _cupsLangString(lang, _("Draft"))); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n", lowdpi, lowdpi / 2); have_qdraft = 1; } else if (ippContainsInteger(quality, IPP_QUALITY_DRAFT)) { - cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Draft"))); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*", lowdpi, lowdpi); have_qdraft = 1; } - cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", lowdpi, lowdpi, lang->language, _cupsLangString(lang, _("Normal"))); + cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n", lowdpi, lowdpi); if (hidpi > lowdpi || ippContainsInteger(quality, IPP_QUALITY_HIGH)) { - cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", hidpi, hidpi, lang->language, _cupsLangString(lang, _("High"))); + cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n", hidpi, hidpi); have_qhigh = 1; } @@ -4087,34 +4047,32 @@ _ppdCreateFromIPP2( pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, ppdname, sizeof(ppdname)); cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname); - cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n" - "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" - "*%s.Translation cupsPrintQuality/%s: \"\"\n" - "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality"))); + cupsFilePuts(fp, "*OpenUI *cupsPrintQuality: PickOne\n" + "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" + "*DefaultcupsPrintQuality: Normal\n"); if (count > 2 || ippContainsInteger(quality, IPP_QUALITY_DRAFT)) { pwg_ppdize_resolution(attr, resolutions[0], &xres, &yres, NULL, 0); cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n", xres, yres); - cupsFilePrintf(fp, "*%s.cupsPrintQuality Draft/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Draft"))); have_qdraft = 1; } pwg_ppdize_resolution(attr, resolutions[count / 2], &xres, &yres, NULL, 0); cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n", xres, yres); - cupsFilePrintf(fp, "*%s.cupsPrintQuality Normal/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Normal"))); if (count > 1 || ippContainsInteger(quality, IPP_QUALITY_HIGH)) { pwg_ppdize_resolution(attr, resolutions[count - 1], &xres, &yres, NULL, 0); cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n", xres, yres); - cupsFilePrintf(fp, "*%s.cupsPrintQuality High/%s: \"\"\n", lang->language, _cupsLangString(lang, _("High"))); have_qhigh = 1; } cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); } else if (is_apple || is_pwg) + { goto bad_ppd; + } else { if ((attr = ippFindAttribute(supported, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL) @@ -4129,21 +4087,20 @@ _ppdCreateFromIPP2( cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname); - cupsFilePrintf(fp, "*OpenUI *cupsPrintQuality: PickOne\n" - "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" - "*%s.Translation cupsPrintQuality/%s: \"\"\n" - "*DefaultcupsPrintQuality: Normal\n", lang->language, _cupsLangString(lang, _("Print Quality"))); + cupsFilePuts(fp, "*OpenUI *cupsPrintQuality: PickOne\n" + "*OrderDependency: 10 AnySetup *cupsPrintQuality\n" + "*DefaultcupsPrintQuality: Normal\n"); if (ippContainsInteger(quality, IPP_QUALITY_DRAFT)) { - cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*%s.cupsPrintQuality Draft/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Draft"))); + cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<>setpagedevice\"\n*", xres, yres); have_qdraft = 1; } - cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n*%s.cupsPrintQuality Normal/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("Normal"))); + cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<>setpagedevice\"\n", xres, yres); if (ippContainsInteger(quality, IPP_QUALITY_HIGH)) { - cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n*%s.cupsPrintQuality High/%s: \"\"\n", xres, yres, lang->language, _cupsLangString(lang, _("High"))); + cupsFilePrintf(fp, "*cupsPrintQuality High: \"<>setpagedevice\"\n", xres, yres); have_qhigh = 1; } cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n"); @@ -4183,8 +4140,8 @@ _ppdCreateFromIPP2( { keyword = ippGetString(attr, i, NULL); -#define PRINTF_COLORMODEL if (!wrote_color) { cupsFilePrintf(fp, "*OpenUI *ColorModel: PickOne\n*OrderDependency: 10 AnySetup *ColorModel\n*%s.Translation ColorModel/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Color Mode"))); wrote_color = 1; } -#define PRINTF_COLOROPTION(name,text,cspace,bpp) { cupsFilePrintf(fp, "*ColorModel %s: \"<>setpagedevice\"\n", name, cspace, bpp); cupsFilePrintf(fp, "*%s.ColorModel %s/%s: \"\"\n", lang->language, name, _cupsLangString(lang, text)); } +#define PRINTF_COLORMODEL if (!wrote_color) { cupsFilePuts(fp, "*OpenUI *ColorModel: PickOne\n*OrderDependency: 10 AnySetup *ColorModel\n"); wrote_color = 1; } +#define PRINTF_COLOROPTION(name,text,cspace,bpp) cupsFilePrintf(fp, "*ColorModel %s/%s: \"<>setpagedevice\"\n", name, text, cspace, bpp); if (!strcasecmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level")) { @@ -4340,17 +4297,13 @@ _ppdCreateFromIPP2( if ((attr = ippFindAttribute(supported, "sides-supported", IPP_TAG_KEYWORD)) != NULL && ippContainsString(attr, "two-sided-long-edge")) { - cupsFilePrintf(fp, "*OpenUI *Duplex: PickOne\n" - "*OrderDependency: 10 AnySetup *Duplex\n" - "*%s.Translation Duplex/%s: \"\"\n" - "*DefaultDuplex: None\n" - "*Duplex None: \"<>setpagedevice\"\n" - "*%s.Duplex None/%s: \"\"\n" - "*Duplex DuplexNoTumble: \"<>setpagedevice\"\n" - "*%s.Duplex DuplexNoTumble/%s: \"\"\n" - "*Duplex DuplexTumble: \"<>setpagedevice\"\n" - "*%s.Duplex DuplexTumble/%s: \"\"\n" - "*CloseUI: *Duplex\n", lang->language, _cupsLangString(lang, _("2-Sided Printing")), lang->language, _cupsLangString(lang, _("Off (1-Sided)")), lang->language, _cupsLangString(lang, _("Long-Edge (Portrait)")), lang->language, _cupsLangString(lang, _("Short-Edge (Landscape)"))); + cupsFilePuts(fp, "*OpenUI *Duplex: PickOne\n" + "*OrderDependency: 10 AnySetup *Duplex\n" + "*DefaultDuplex: None\n" + "*Duplex None: \"<>setpagedevice\"\n" + "*Duplex DuplexNoTumble: \"<>setpagedevice\"\n" + "*Duplex DuplexTumble: \"<>setpagedevice\"\n" + "*CloseUI: *Duplex\n"); if ((attr = ippFindAttribute(supported, "urf-supported", IPP_TAG_KEYWORD)) != NULL) { @@ -4429,12 +4382,9 @@ _ppdCreateFromIPP2( pwg_ppdize_name(keyword, ppdname, sizeof(ppdname)); snprintf(msgid, sizeof(msgid), "output-bin.%s", keyword); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; cupsFilePrintf(fp, "*OutputBin %s: \"\"\n", ppdname); - cupsFilePrintf(fp, "*%s.OutputBin %s/%s: \"\"\n", lang->language, ppdname, msgstr); + ppd_put_strings(fp, langs, "OutputBin", ppdname, msgid); if ((tray_ptr = ippGetOctetString(trays, i, &tray_len)) != NULL) { @@ -4534,10 +4484,10 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "*OpenUI *StapleLocation: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *StapleLocation\n"); - cupsFilePrintf(fp, "*%s.Translation StapleLocation/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Staple"))); + ppd_put_strings(fp, langs, "Translation", "StapleLocation", "finishings.4"); cupsFilePuts(fp, "*DefaultStapleLocation: None\n"); cupsFilePuts(fp, "*StapleLocation None: \"\"\n"); - cupsFilePrintf(fp, "*%s.StapleLocation None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); + ppd_put_strings(fp, langs, "StapleLocation", "None", "finishings.3"); for (; i < count; i ++) { @@ -4553,9 +4503,6 @@ _ppdCreateFromIPP2( cupsArrayAdd(names, (char *)keyword); snprintf(msgid, sizeof(msgid), "finishings.%d", value); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE) ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE]; @@ -4570,7 +4517,7 @@ _ppdCreateFromIPP2( continue; cupsFilePrintf(fp, "*StapleLocation %s: \"\"\n", ppd_keyword); - cupsFilePrintf(fp, "*%s.StapleLocation %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr); + ppd_put_strings(fp, langs, "StapleLocation", ppd_keyword, msgid); cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*StapleLocation %s\"\n", value, keyword, ppd_keyword); } @@ -4612,10 +4559,10 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "*OpenUI *FoldType: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *FoldType\n"); - cupsFilePrintf(fp, "*%s.Translation FoldType/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Fold"))); + ppd_put_strings(fp, langs, "Translation", "FoldType", "finishings.10"); cupsFilePuts(fp, "*DefaultFoldType: None\n"); cupsFilePuts(fp, "*FoldType None: \"\"\n"); - cupsFilePrintf(fp, "*%s.FoldType None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); + ppd_put_strings(fp, langs, "FoldType", "None", "finishings.3"); for (; i < count; i ++) { @@ -4633,9 +4580,6 @@ _ppdCreateFromIPP2( cupsArrayAdd(names, (char *)keyword); snprintf(msgid, sizeof(msgid), "finishings.%d", value); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE) ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE]; @@ -4650,7 +4594,7 @@ _ppdCreateFromIPP2( continue; cupsFilePrintf(fp, "*FoldType %s: \"\"\n", ppd_keyword); - cupsFilePrintf(fp, "*%s.FoldType %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr); + ppd_put_strings(fp, langs, "FoldType", ppd_keyword, msgid); cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*FoldType %s\"\n", value, keyword, ppd_keyword); } @@ -4700,10 +4644,10 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "*OpenUI *PunchMedia: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *PunchMedia\n"); - cupsFilePrintf(fp, "*%s.Translation PunchMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Punch"))); + ppd_put_strings(fp, langs, "Translation", "PunchMedia", "finishings.5"); cupsFilePuts(fp, "*DefaultPunchMedia: None\n"); cupsFilePuts(fp, "*PunchMedia None: \"\"\n"); - cupsFilePrintf(fp, "*%s.PunchMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); + ppd_put_strings(fp, langs, "PunchMedia", "None", "finishings.3"); for (i = 0; i < count; i ++) { @@ -4721,9 +4665,6 @@ _ppdCreateFromIPP2( cupsArrayAdd(names, (char *)keyword); snprintf(msgid, sizeof(msgid), "finishings.%d", value); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; if (value >= IPP_FINISHINGS_NONE && value <= IPP_FINISHINGS_LAMINATE) ppd_keyword = base_keywords[value - IPP_FINISHINGS_NONE]; @@ -4738,7 +4679,7 @@ _ppdCreateFromIPP2( continue; cupsFilePrintf(fp, "*PunchMedia %s: \"\"\n", ppd_keyword); - cupsFilePrintf(fp, "*%s.PunchMedia %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr); + ppd_put_strings(fp, langs, "PunchMedia", ppd_keyword, msgid); cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*PunchMedia %s\"\n", value, keyword, ppd_keyword); } @@ -4755,7 +4696,7 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "*OpenUI *Booklet: Boolean\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *Booklet\n"); - cupsFilePrintf(fp, "*%s.Translation Booklet/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Booklet"))); + ppd_put_strings(fp, langs, "Translation", "StapleLocation", "finishings.13"); cupsFilePuts(fp, "*DefaultBooklet: False\n"); cupsFilePuts(fp, "*Booklet False: \"\"\n"); cupsFilePuts(fp, "*Booklet True: \"\"\n"); @@ -4790,10 +4731,10 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "*OpenUI *CutMedia: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *CutMedia\n"); - cupsFilePrintf(fp, "*%s.Translation CutMedia/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Cut"))); + ppd_put_strings(fp, langs, "Translation", "CutMedia", "finishings.11"); cupsFilePuts(fp, "*DefaultCutMedia: None\n"); cupsFilePuts(fp, "*CutMedia None: \"\"\n"); - cupsFilePrintf(fp, "*%s.CutMedia None/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); + ppd_put_strings(fp, langs, "CutMedia", "None", "finishings.3"); for (i = 0; i < count; i ++) { @@ -4809,9 +4750,6 @@ _ppdCreateFromIPP2( cupsArrayAdd(names, (char *)keyword); snprintf(msgid, sizeof(msgid), "finishings.%d", value); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; if (value == IPP_FINISHINGS_TRIM) ppd_keyword = "Auto"; @@ -4819,7 +4757,7 @@ _ppdCreateFromIPP2( ppd_keyword = trim_keywords[value - IPP_FINISHINGS_TRIM_AFTER_PAGES]; cupsFilePrintf(fp, "*CutMedia %s: \"\"\n", ppd_keyword); - cupsFilePrintf(fp, "*%s.CutMedia %s/%s: \"\"\n", lang->language, ppd_keyword, msgstr); + ppd_put_strings(fp, langs, "CutMedia", ppd_keyword, msgid); cupsFilePrintf(fp, "*cupsIPPFinishings %d/%s: \"*CutMedia %s\"\n", value, keyword, ppd_keyword); } @@ -4837,10 +4775,10 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "*OpenUI *cupsFinishingTemplate: PickOne\n"); cupsFilePuts(fp, "*OrderDependency: 10 AnySetup *cupsFinishingTemplate\n"); - cupsFilePrintf(fp, "*%s.Translation cupsFinishingTemplate/%s: \"\"\n", lang->language, _cupsLangString(lang, _("Finishing Preset"))); + ppd_put_strings(fp, langs, "Translation", "cupsFinishingTemplate", "finishing-template"); cupsFilePuts(fp, "*DefaultcupsFinishingTemplate: none\n"); cupsFilePuts(fp, "*cupsFinishingTemplate none: \"\"\n"); - cupsFilePrintf(fp, "*%s.cupsFinishingTemplate none/%s: \"\"\n", lang->language, _cupsLangString(lang, _("None"))); + ppd_put_strings(fp, langs, "cupsFinishingTemplate", "none", "finishings.3"); templates = cupsArrayNew((cups_array_func_t)_cupsArrayStrcmp, NULL); count = ippGetCount(attr); @@ -4859,9 +4797,6 @@ _ppdCreateFromIPP2( cupsArrayAdd(templates, (void *)keyword); snprintf(msgid, sizeof(msgid), "finishing-template.%s", keyword); - if ((msgstr = _cupsLangString(lang, msgid)) == msgid || !strcmp(msgid, msgstr)) - if ((msgstr = _cupsMessageLookup(strings, msgid)) == msgid) - msgstr = keyword; cupsFilePrintf(fp, "*cupsFinishingTemplate %s: \"\n", keyword); for (finishing_attr = ippFirstAttribute(finishing_col); finishing_attr; finishing_attr = ippNextAttribute(finishing_col)) @@ -4876,7 +4811,7 @@ _ppdCreateFromIPP2( } } cupsFilePuts(fp, "\"\n"); - cupsFilePrintf(fp, "*%s.cupsFinishingTemplate %s/%s: \"\"\n", lang->language, keyword, msgstr); + ppd_put_strings(fp, langs, "cupsFinishingTemplate", keyword, msgid); cupsFilePuts(fp, "*End\n"); } @@ -4891,7 +4826,7 @@ _ppdCreateFromIPP2( cupsFilePrintf(fp, " %s", fin_option); cupsFilePuts(fp, "\"\n"); - cupsFilePuts(fp, "*cupsUIResolver finishing-template: \"*cupsFinishingTemplate None"); + cupsFilePuts(fp, "*cupsUIResolver finishing-template: \"*cupsFinishingTemplate none"); for (fin_option = (const char *)cupsArrayFirst(fin_options); fin_option; fin_option = (const char *)cupsArrayNext(fin_options)) cupsFilePrintf(fp, " %s None", fin_option); cupsFilePuts(fp, "\"\n"); @@ -4912,9 +4847,8 @@ _ppdCreateFromIPP2( { ipp_t *preset = ippGetCollection(attr, i); /* Preset collection */ - const char *preset_name = ippGetString(ippFindAttribute(preset, "preset-name", IPP_TAG_ZERO), 0, NULL), + const char *preset_name = ippGetString(ippFindAttribute(preset, "preset-name", IPP_TAG_ZERO), 0, NULL); /* Preset name */ - *localized_name; /* Localized preset name */ ipp_attribute_t *member; /* Member attribute in preset */ const char *member_name; /* Member attribute name */ char member_value[256]; /* Member attribute value */ @@ -5041,8 +4975,8 @@ _ppdCreateFromIPP2( cupsFilePuts(fp, "\"\n*End\n"); - if ((localized_name = _cupsMessageLookup(strings, preset_name)) != preset_name) - cupsFilePrintf(fp, "*%s.APPrinterPreset %s/%s: \"\"\n", lang->language, preset_name, localized_name); +// if ((localized_name = _cupsMessageLookup(strings, preset_name)) != preset_name) +// cupsFilePrintf(fp, "*%s.APPrinterPreset %s/%s: \"\"\n", lang->language, preset_name, localized_name); } } @@ -5062,7 +4996,15 @@ _ppdCreateFromIPP2( cupsFileClose(fp); - _cupsMessageFree(strings); + for (lang = langs; lang;) + { + cups_lang_t *next = lang->next; + + cupsArrayDelete(lang->strings); + free(lang); + + lang = next; + } return (buffer); @@ -5073,11 +5015,20 @@ _ppdCreateFromIPP2( bad_ppd: cupsFileClose(fp); + + for (lang = langs; lang;) + { + cups_lang_t *next = lang->next; + + cupsArrayDelete(lang->strings); + free(lang); + + lang = next; + } + unlink(buffer); *buffer = '\0'; - _cupsMessageFree(strings); - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Printer does not support required IPP attributes or document formats."), 1); return (NULL); @@ -5277,6 +5228,134 @@ cups_connect(http_t **http, /* IO - Current HTTP connection */ } +/* + * 'cups_get_languages()' - Get the languages to load for PPDs. + */ + +static cups_array_t * /* O - Array of languages */ +cups_get_languages(void) +{ + cups_array_t *languages = NULL; /* Array of languages */ + cups_file_t *fp; /* CUPS_SERVERROOT/cups-files.conf file */ + char filename[1024]; /* Filename */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + snprintf(filename, sizeof(filename), "%s/cups-files.conf", cg->cups_serverroot); + + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + /* + * Read the cups-files.conf file, looking for a Languages directive... + */ + + char line[1024], /* Line from file */ + *value; /* Value from line */ + int linenum = 0; /* Current line number */ + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!_cups_strcasecmp(line, "Languages") && value) + { + languages = cupsArrayNewStrings(value, ' '); + break; + } + } + + cupsFileClose(fp); + } + + if (!languages) + { + /* + * No Languages directive in CUPS_SERVERROOT/cups-files.conf, so use the + * current locale... + */ + + cups_lang_t *deflang; /* Default language */ + + languages = cupsArrayNewStrings(NULL, ' '); + deflang = cupsLangDefault(); + + cupsArrayAdd(languages, deflang->language); + } + + return (languages); +} + + +/* + * 'cups_get_strings()' - Get the strings for the specified language. + */ + +static cups_lang_t * /* O - Language data */ +cups_get_strings( + http_t **http, /* IO - Current HTTP connection */ + const char *printer_uri, /* I - Printer URI */ + const char *language) /* I - Language name */ +{ + cups_lang_t *lang = NULL; /* Language data */ + char resource[256]; /* Resource path for printer */ + ipp_t *request, /* IPP request */ + *response = NULL; /* IPP response */ + const char *strings_uri; /* "printer-strings-uri" value */ + char strings_file[1024] = "";/* Strings filename */ + + + /* + * Connect to the printer... + */ + + if (!cups_connect(http, printer_uri, resource, sizeof(resource))) + goto done; + + /* + * Get the URL for the corresponding language strings... + */ + + request = ippNew(); + ippSetOperation(request, IPP_OP_GET_PRINTER_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", /*language*/NULL, "utf-8"); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", /*language*/NULL, language); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", /*language*/NULL, printer_uri); + + response = cupsDoRequest(*http, request, resource); + + if ((strings_uri = ippGetString(ippFindAttribute(response, "printer-strings-uri", IPP_TAG_URI), 0, NULL)) != NULL) + { + /* + * Download the strings file... + */ + + if (!cups_get_url(http, strings_uri, ".strings", strings_file, sizeof(strings_file))) + goto done; + + /* + * Allocate memory... + */ + + if ((lang = (cups_lang_t *)calloc(1, sizeof(cups_lang_t))) == NULL) + goto done; + + /* + * Load the strings... + */ + + cupsCopyString(lang->language, language, sizeof(lang->language)); + lang->strings = _cupsMessageLoad(strings_file, _CUPS_MESSAGE_STRINGS); + } + + done: + + ippDelete(response); + + if (strings_file[0]) + unlink(strings_file); + + return (lang); +} + + /* * 'cups_get_url()' - Get a copy of the file at the given URL. */ @@ -5284,6 +5363,7 @@ cups_connect(http_t **http, /* IO - Current HTTP connection */ static int /* O - 1 on success, 0 on failure */ cups_get_url(http_t **http, /* IO - Current HTTP connection */ const char *url, /* I - URL to get */ + const char *suffix, /* I - Filename suffix */ char *name, /* I - Temporary filename */ size_t namesize) /* I - Size of temporary filename buffer */ { @@ -5295,7 +5375,7 @@ cups_get_url(http_t **http, /* IO - Current HTTP connection */ if (!cups_connect(http, url, resource, sizeof(resource))) return (0); - if ((fd = cupsTempFd(name, (int)namesize)) < 0) + if ((fd = cupsCreateTempFd("ippeve", suffix, name, namesize)) < 0) return (0); status = cupsGetFd(*http, resource, fd); @@ -5313,6 +5393,29 @@ cups_get_url(http_t **http, /* IO - Current HTTP connection */ } +/* + * 'ppd_put_strings()' - Write localization attributes to a PPD file. + */ + +static void +ppd_put_strings(cups_file_t *fp, /* I - PPD file */ + cups_lang_t *langs, /* I - Languages */ + const char *ppd_option,/* I - PPD option */ + const char *ppd_choice,/* I - PPD choice */ + const char *pwg_msgid) /* I - PWG message ID */ +{ + cups_lang_t *lang; /* Current language */ + const char *text; /* Localized text */ + + + for (lang = langs; lang; lang = lang->next) + { + if ((text = _cupsLangString(lang, pwg_msgid)) != pwg_msgid) + cupsFilePrintf(fp, "*%s.%s %s/%s: \"\"\n", lang->language, ppd_option, ppd_choice, text); + } +} + + /* * 'pwg_add_finishing()' - Add a finishings value. */ diff --git a/cups/ppd-private.h b/cups/ppd-private.h index fc65d37334..f264406cce 100644 --- a/cups/ppd-private.h +++ b/cups/ppd-private.h @@ -13,20 +13,9 @@ #ifndef _CUPS_PPD_PRIVATE_H_ # define _CUPS_PPD_PRIVATE_H_ - -/* - * Include necessary headers... - */ - # include # include # include "pwg-private.h" - - -/* - * C++ magic... - */ - # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ @@ -147,7 +136,8 @@ struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/ char *password; /* cupsJobPassword value */ cups_array_t *mandatory; /* cupsMandatory value */ char *charge_info_uri; /* cupsChargeInfoURI value */ - cups_array_t *strings; /* Localization strings */ + cups_lang_t *langs; /* Localization languages/strings */ + cups_array_t *strings; /* TODO: REMOVE ME */ cups_array_t *support_files; /* Support files - ICC profiles, etc. */ }; @@ -160,65 +150,36 @@ extern int _cupsConvertOptions(ipp_t *request, ppd_file_t *ppd, _ppd_cache_t *p extern int _cupsRasterExecPS(cups_page_header2_t *h, int *preferred_bits, const char *code) _CUPS_NONNULL(3) _CUPS_PRIVATE; extern int _cupsRasterInterpretPPD(cups_page_header2_t *h, ppd_file_t *ppd, int num_options, cups_option_t *options, cups_interpret_cb_t func) _CUPS_PRIVATE; -extern _ppd_cache_t *_ppdCacheCreateWithFile(const char *filename, - ipp_t **attrs) _CUPS_PRIVATE; +extern _ppd_cache_t *_ppdCacheCreateWithFile(const char *filename, ipp_t **attrs) _CUPS_PRIVATE; extern _ppd_cache_t *_ppdCacheCreateWithPPD(ppd_file_t *ppd) _CUPS_PRIVATE; extern void _ppdCacheDestroy(_ppd_cache_t *pc) _CUPS_PRIVATE; -extern const char *_ppdCacheGetBin(_ppd_cache_t *pc, - const char *output_bin) _CUPS_PRIVATE; -extern int _ppdCacheGetFinishingOptions(_ppd_cache_t *pc, - ipp_t *job, - ipp_finishings_t value, - int num_options, - cups_option_t **options) _CUPS_PRIVATE; +extern const char *_ppdCacheGetBin(_ppd_cache_t *pc, const char *output_bin) _CUPS_PRIVATE; +extern int _ppdCacheGetFinishingOptions(_ppd_cache_t *pc, ipp_t *job, ipp_finishings_t value, int num_options, cups_option_t **options) _CUPS_PRIVATE; extern int _ppdCacheGetFinishingValues(ppd_file_t *ppd, _ppd_cache_t *pc, int max_values, int *values) _CUPS_PRIVATE; -extern const char *_ppdCacheGetInputSlot(_ppd_cache_t *pc, ipp_t *job, - const char *keyword) _CUPS_PRIVATE; -extern const char *_ppdCacheGetMediaType(_ppd_cache_t *pc, ipp_t *job, - const char *keyword) _CUPS_PRIVATE; -extern const char *_ppdCacheGetOutputBin(_ppd_cache_t *pc, - const char *keyword) _CUPS_PRIVATE; -extern const char *_ppdCacheGetPageSize(_ppd_cache_t *pc, ipp_t *job, - const char *keyword, int *exact) _CUPS_PRIVATE; -extern pwg_size_t *_ppdCacheGetSize(_ppd_cache_t *pc, - const char *page_size) _CUPS_PRIVATE; -extern const char *_ppdCacheGetSource(_ppd_cache_t *pc, - const char *input_slot) _CUPS_PRIVATE; -extern const char *_ppdCacheGetType(_ppd_cache_t *pc, - const char *media_type) _CUPS_PRIVATE; -extern int _ppdCacheWriteFile(_ppd_cache_t *pc, - const char *filename, ipp_t *attrs) _CUPS_PRIVATE; +extern const char *_ppdCacheGetInputSlot(_ppd_cache_t *pc, ipp_t *job, const char *keyword) _CUPS_PRIVATE; +extern const char *_ppdCacheGetMediaType(_ppd_cache_t *pc, ipp_t *job, const char *keyword) _CUPS_PRIVATE; +extern const char *_ppdCacheGetOutputBin(_ppd_cache_t *pc, const char *keyword) _CUPS_PRIVATE; +extern const char *_ppdCacheGetPageSize(_ppd_cache_t *pc, ipp_t *job, const char *keyword, int *exact) _CUPS_PRIVATE; +extern pwg_size_t *_ppdCacheGetSize(_ppd_cache_t *pc, const char *page_size) _CUPS_PRIVATE; +extern const char *_ppdCacheGetSource(_ppd_cache_t *pc, const char *input_slot) _CUPS_PRIVATE; +extern const char *_ppdCacheGetType(_ppd_cache_t *pc, const char *media_type) _CUPS_PRIVATE; +extern int _ppdCacheWriteFile(_ppd_cache_t *pc, const char *filename, ipp_t *attrs) _CUPS_PRIVATE; extern char *_ppdCreateFromIPP(char *buffer, size_t bufsize, ipp_t *response) _CUPS_PRIVATE; -extern char *_ppdCreateFromIPP2(char *buffer, size_t bufsize, ipp_t *response, cups_lang_t *lang) _CUPS_PRIVATE; extern void _ppdFreeLanguages(cups_array_t *languages) _CUPS_PRIVATE; extern cups_encoding_t _ppdGetEncoding(const char *name) _CUPS_PRIVATE; extern cups_array_t *_ppdGetLanguages(ppd_file_t *ppd) _CUPS_PRIVATE; extern _ppd_globals_t *_ppdGlobals(void) _CUPS_PRIVATE; extern unsigned _ppdHashName(const char *name) _CUPS_PRIVATE; -extern ppd_attr_t *_ppdLocalizedAttr(ppd_file_t *ppd, const char *keyword, - const char *spec, const char *ll_CC) _CUPS_PRIVATE; -extern char *_ppdNormalizeMakeAndModel(const char *make_and_model, - char *buffer, - size_t bufsize) _CUPS_PRIVATE; -extern ppd_file_t *_ppdOpen(cups_file_t *fp, - _ppd_localization_t localization) _CUPS_PRIVATE; -extern ppd_file_t *_ppdOpenFile(const char *filename, - _ppd_localization_t localization) _CUPS_PRIVATE; -extern int _ppdParseOptions(const char *s, int num_options, - cups_option_t **options, - _ppd_parse_t which) _CUPS_PRIVATE; -extern const char *_pwgInputSlotForSource(const char *media_source, - char *name, size_t namesize) _CUPS_PRIVATE; -extern const char *_pwgMediaTypeForType(const char *media_type, - char *name, size_t namesize) _CUPS_PRIVATE; -extern const char *_pwgPageSizeForMedia(pwg_media_t *media, - char *name, size_t namesize) _CUPS_PRIVATE; +extern ppd_attr_t *_ppdLocalizedAttr(ppd_file_t *ppd, const char *keyword, const char *spec, const char *ll_CC) _CUPS_PRIVATE; +extern char *_ppdNormalizeMakeAndModel(const char *make_and_model, char *buffer, size_t bufsize) _CUPS_PRIVATE; +extern ppd_file_t *_ppdOpen(cups_file_t *fp, _ppd_localization_t localization) _CUPS_PRIVATE; +extern ppd_file_t *_ppdOpenFile(const char *filename, _ppd_localization_t localization) _CUPS_PRIVATE; +extern int _ppdParseOptions(const char *s, int num_options, cups_option_t **options, _ppd_parse_t which) _CUPS_PRIVATE; +extern const char *_pwgInputSlotForSource(const char *media_source, char *name, size_t namesize) _CUPS_PRIVATE; +extern const char *_pwgMediaTypeForType(const char *media_type, char *name, size_t namesize) _CUPS_PRIVATE; +extern const char *_pwgPageSizeForMedia(pwg_media_t *media, char *name, size_t namesize) _CUPS_PRIVATE; -/* - * C++ magic... - */ - # ifdef __cplusplus } # endif /* __cplusplus */