4 * I18N/language support for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2005 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * cupsEncodingName() - Return the character encoding name string
29 * for the given encoding enumeration.
30 * cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
31 * for the given language.
32 * cupsLangFlush() - Flush all language data out of the cache.
33 * cupsLangFree() - Free language data.
34 * cupsLangGet() - Get a language.
35 * _cupsRestoreLocale() - Restore the original locale...
36 * _cupsSaveLocale() - Set the locale and save a copy of the old locale...
37 * appleLangDefault() - Get the default locale string.
38 * cups_cache_lookup() - Lookup a language in the cache...
42 * Include necessary headers...
48 #ifdef HAVE_LANGINFO_H
49 # include <langinfo.h>
50 #endif /* HAVE_LANGINFO_H */
66 # include <CoreFoundation/CoreFoundation.h>
67 static const char *appleLangDefault(void);
68 #endif /* __APPLE__ */
70 static cups_lang_t
*cups_cache_lookup(const char *name
,
71 cups_encoding_t encoding
);
78 static cups_lang_t
*lang_cache
= NULL
;
79 /* Language string cache */
80 static const char *lang_blank
= "";
81 /* Blank constant string */
82 static const char * const lang_encodings
[] =
83 { /* Encoding strings */
84 "us-ascii", "iso-8859-1",
85 "iso-8859-2", "iso-8859-3",
86 "iso-8859-4", "iso-8859-5",
87 "iso-8859-6", "iso-8859-7",
88 "iso-8859-8", "iso-8859-9",
89 "iso-8859-10", "utf-8",
90 "iso-8859-13", "iso-8859-14",
91 "iso-8859-15", "windows-874",
92 "windows-1250", "windows-1251",
93 "windows-1252", "windows-1253",
94 "windows-1254", "windows-1255",
95 "windows-1256", "windows-1257",
96 "windows-1258", "koi8-r",
97 "koi8-u", "iso-8859-11",
98 "iso-8859-16", "unknown",
100 "unknown", "unknown",
101 "unknown", "unknown",
102 "unknown", "unknown",
103 "unknown", "unknown",
104 "unknown", "unknown",
105 "unknown", "unknown",
106 "unknown", "unknown",
107 "unknown", "unknown",
108 "unknown", "unknown",
109 "unknown", "unknown",
110 "unknown", "unknown",
111 "unknown", "unknown",
112 "unknown", "unknown",
113 "unknown", "unknown",
114 "unknown", "unknown",
115 "unknown", "unknown",
116 "windows-932", "windows-936",
117 "windows-949", "windows-950",
118 "windows-1361", "unknown",
119 "unknown", "unknown",
120 "unknown", "unknown",
121 "unknown", "unknown",
122 "unknown", "unknown",
123 "unknown", "unknown",
124 "unknown", "unknown",
125 "unknown", "unknown",
126 "unknown", "unknown",
127 "unknown", "unknown",
128 "unknown", "unknown",
129 "unknown", "unknown",
130 "unknown", "unknown",
131 "unknown", "unknown",
132 "unknown", "unknown",
133 "unknown", "unknown",
134 "unknown", "unknown",
135 "unknown", "unknown",
136 "unknown", "unknown",
137 "unknown", "unknown",
138 "unknown", "unknown",
139 "unknown", "unknown",
140 "unknown", "unknown",
141 "unknown", "unknown",
142 "unknown", "unknown",
143 "unknown", "unknown",
144 "unknown", "unknown",
145 "unknown", "unknown",
146 "unknown", "unknown",
147 "unknown", "unknown",
151 static const char *const lang_default
[] =
152 { /* Default POSIX locale */
159 * 'cupsEncodingName()' - Return the character encoding name string
160 * for the given encoding enumeration.
163 const char * /* O - Character encoding */
164 cupsEncodingName(cups_encoding_t encoding
)
165 /* I - Encoding enum */
168 encoding
>= (sizeof(lang_encodings
) / sizeof(const char *)))
169 return (lang_encodings
[0]);
171 return (lang_encodings
[encoding
]);
176 * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.)
177 * for the given language.
180 const char * /* O - Character encoding */
181 cupsLangEncoding(cups_lang_t
*lang
) /* I - Language data */
184 return ((char*)lang_encodings
[0]);
186 return ((char*)lang_encodings
[lang
->encoding
]);
191 * 'cupsLangFlush()' - Flush all language data out of the cache.
197 int i
; /* Looping var */
198 cups_lang_t
*lang
, /* Current language */
199 *next
; /* Next language */
203 * Free all languages in the cache...
206 for (lang
= lang_cache
; lang
!= NULL
; lang
= next
)
209 * Free all messages...
212 for (i
= 0; i
< CUPS_MSG_MAX
; i
++)
213 if (lang
->messages
[i
] != NULL
&& lang
->messages
[i
] != lang_blank
)
214 free(lang
->messages
[i
]);
217 * Then free the language structure itself...
229 * 'cupsLangFree()' - Free language data.
231 * This does not actually free anything; use cupsLangFlush() for that.
235 cupsLangFree(cups_lang_t
*lang
) /* I - Language to free */
237 if (lang
!= NULL
&& lang
->used
> 0)
243 * 'cupsLangGet()' - Get a language.
246 cups_lang_t
* /* O - Language data */
247 cupsLangGet(const char *language
) /* I - Language or locale */
249 int i
, count
; /* Looping vars */
250 char locale
[255], /* Copy of locale name */
251 langname
[16], /* Requested language name */
252 country
[16], /* Country code */
253 charset
[16], /* Character set */
255 *csptr
, /* Pointer to CODESET string */
257 *ptr
, /* Pointer into language/charset */
258 real
[48], /* Real language name */
259 filename
[1024], /* Filename for language locale file */
260 *localedir
; /* Directory for locale files */
261 cups_encoding_t encoding
; /* Encoding to use */
262 FILE *fp
; /* Language locale file pointer */
263 char line
[1024]; /* Line from file */
264 cups_msg_t msg
; /* Message number */
265 char *text
; /* Message text */
266 cups_lang_t
*lang
; /* Current language... */
267 char *oldlocale
; /* Old locale name */
268 static const char * const locale_encodings
[] =
269 { /* Locale charset names */
270 "ASCII", "ISO88591", "ISO88592", "ISO88593",
271 "ISO88594", "ISO88595", "ISO88596", "ISO88597",
272 "ISO88598", "ISO88599", "ISO885910", "UTF8",
273 "ISO885913", "ISO885914", "ISO885915", "CP874",
274 "CP1250", "CP1251", "CP1252", "CP1253",
275 "CP1254", "CP1255", "CP1256", "CP1257",
276 "CP1258", "KOI8R", "KOI8U", "ISO885911",
277 "ISO885916", "", "", "",
288 "CP932", "CP936", "CP949", "CP950",
289 "CP1361", "", "", "",
306 "EUCCN", "EUCJP", "EUCKR", "EUCTW"
310 DEBUG_printf(("cupsLangGet(language=\"%s\")\n", language
? language
: "(null)"));
314 * Apple's setlocale doesn't give us the user's localization
315 * preference so we have to look it up this way...
318 if (language
== NULL
)
319 language
= appleLangDefault();
321 if (language
== NULL
)
324 * First see if the locale has been set; if it is still "C" or
325 * "POSIX", set the locale to the default...
329 ptr
= setlocale(LC_MESSAGES
, NULL
);
331 ptr
= setlocale(LC_ALL
, NULL
);
332 # endif /* LC_MESSAGES */
334 DEBUG_printf(("cupsLangGet: current locale is \"%s\"\n",
335 ptr
? ptr
: "(null)"));
337 if (!ptr
|| !strcmp(ptr
, "C") || !strcmp(ptr
, "POSIX"))
340 ptr
= setlocale(LC_MESSAGES
, "");
341 setlocale(LC_CTYPE
, "");
344 ptr
= setlocale(LC_ALL
, "");
345 # endif /* LC_MESSAGES */
349 strlcpy(locale
, ptr
, sizeof(locale
));
352 DEBUG_printf(("cupsLangGet: new language value is \"%s\"\n",
353 language
? language
: "(null)"));
356 #endif /* __APPLE__ */
359 * If "language" is NULL at this point, then chances are we are using
360 * a language that is not installed for the base OS.
366 * Switch to the value of the "LANG" environment variable, and if
367 * that is NULL as well, use "C".
370 if ((language
= getenv("LANG")) == NULL
)
375 * Set the charset to "unknown"...
382 * On systems that support the nl_langinfo(CODESET) call, use
383 * this value as the character set...
386 if ((csptr
= nl_langinfo(CODESET
)) != NULL
)
389 * Copy all of the letters and numbers in the CODESET string...
392 for (ptr
= charset
; *csptr
; csptr
++)
393 if (isalnum(*csptr
& 255) && ptr
< (charset
+ sizeof(charset
) - 1))
398 DEBUG_printf(("cupsLangGet: charset set to \"%s\" via nl_langinfo(CODESET)...\n",
404 * Set the locale back to POSIX while we do string ops, since
405 * apparently some buggy C libraries break ctype() for non-I18N
409 #if defined(__APPLE__)
410 /* The ctype bug isn't in Apple's libc */
411 #elif !defined(LC_CTYPE)
412 oldlocale
= _cupsSaveLocale(LC_ALL
, "C");
414 oldlocale
= _cupsSaveLocale(LC_CTYPE
, "C");
415 #endif /* __APPLE__ */
418 * Parse the language string passed in to a locale string. "C" is the
419 * standard POSIX locale and is copied unchanged. Otherwise the
420 * language string is converted from ll-cc[.charset] (language-country)
421 * to ll_CC[.CHARSET] to match the file naming convention used by all
422 * POSIX-compliant operating systems. Invalid language names are mapped
423 * to the POSIX locale.
428 if (language
== NULL
|| !language
[0] ||
429 strcmp(language
, "POSIX") == 0)
430 strcpy(langname
, "C");
434 * Copy the parts of the locale string over safely...
437 for (ptr
= langname
; *language
; language
++)
438 if (*language
== '_' || *language
== '-' || *language
== '.')
440 else if (ptr
< (langname
+ sizeof(langname
) - 1))
441 *ptr
++ = tolower(*language
& 255);
445 if (*language
== '_' || *language
== '-')
448 * Copy the country code...
451 for (language
++, ptr
= country
; *language
; language
++)
452 if (*language
== '.')
454 else if (ptr
< (country
+ sizeof(country
) - 1))
455 *ptr
++ = toupper(*language
& 255);
460 if (*language
== '.' && !charset
[0])
463 * Copy the encoding...
466 for (language
++, ptr
= charset
; *language
; language
++)
467 if (isalnum(*language
& 255) && ptr
< (charset
+ sizeof(charset
) - 1))
468 *ptr
++ = toupper(*language
& 255);
474 * Force a POSIX locale for an invalid language name...
477 if (strlen(langname
) != 2)
479 strcpy(langname
, "C");
486 * Restore the locale...
489 #if defined(__APPLE__)
490 /* The ctype bug isn't in Apple's libc */
491 #elif !defined(LC_CTYPE)
492 _cupsRestoreLocale(LC_ALL
, oldlocale
);
494 _cupsRestoreLocale(LC_CTYPE
, oldlocale
);
495 #endif /* __APPLE__ */
497 DEBUG_printf(("cupsLangGet: langname=\"%s\", country=\"%s\", charset=\"%s\"\n",
498 langname
, country
, charset
));
501 * Figure out the desired encoding...
504 encoding
= CUPS_AUTO_ENCODING
;
508 for (i
= 0; i
< (int)(sizeof(locale_encodings
) / sizeof(locale_encodings
[0])); i
++)
509 if (!strcasecmp(charset
, locale_encodings
[i
]))
511 encoding
= (cups_encoding_t
)i
;
516 DEBUG_printf(("cupsLangGet: encoding=%d(%s)\n", encoding
,
517 encoding
== CUPS_AUTO_ENCODING
? "auto" :
518 lang_encodings
[encoding
]));
521 * Now find the message catalog for this locale...
524 if ((localedir
= getenv("LOCALEDIR")) == NULL
)
525 localedir
= CUPS_LOCALEDIR
;
528 * See if we already have this language/country loaded...
531 snprintf(real
, sizeof(real
), "%s_%s", langname
, country
);
533 if ((lang
= cups_cache_lookup(real
, encoding
)) != NULL
)
536 snprintf(filename
, sizeof(filename
), "%s/%s/cups_%s", localedir
, real
, real
);
538 if (!country
[0] || access(filename
, 0))
541 * Country localization not available, look for generic localization...
544 if ((lang
= cups_cache_lookup(langname
, encoding
)) != NULL
)
547 snprintf(filename
, sizeof(filename
), "%s/%s/cups_%s", localedir
,
550 if (access(filename
, 0))
553 * No generic localization, so use POSIX...
557 snprintf(filename
, sizeof(filename
), "%s/C/cups_C", localedir
);
560 strcpy(real
, langname
);
564 * Open the messages file; the first line contains the default
565 * language encoding (us-ascii, iso-8859-1, etc.), and the rest are
566 * messages consisting of:
568 * #### SP message text
574 * If the line starts with a number, then message processing picks up
575 * where the number indicates. Otherwise the last message number is
578 * All leading whitespace is deleted.
581 if (strcmp(real
, "C"))
582 fp
= fopen(filename
, "r");
587 strlcpy(line
, lang_default
[0], sizeof(line
));
588 else if (fgets(line
, sizeof(line
), fp
) == NULL
)
591 * Can't read encoding!
598 i
= strlen(line
) - 1;
600 line
[i
] = '\0'; /* Strip LF */
603 * See if there is a free language available; if so, use that
607 for (lang
= lang_cache
; lang
!= NULL
; lang
= lang
->next
)
614 * Allocate memory for the language and add it to the cache.
617 if ((lang
= calloc(sizeof(cups_lang_t
), 1)) == NULL
)
623 lang
->next
= lang_cache
;
628 * Free all old strings as needed...
631 for (i
= 0; i
< CUPS_MSG_MAX
; i
++)
633 if (lang
->messages
[i
] != NULL
&& lang
->messages
[i
] != lang_blank
)
634 free(lang
->messages
[i
]);
636 lang
->messages
[i
] = (char *)lang_blank
;
640 * Then assign the language and encoding fields...
644 strlcpy(lang
->language
, real
, sizeof(lang
->language
));
646 if (encoding
!= CUPS_AUTO_ENCODING
)
647 lang
->encoding
= encoding
;
650 lang
->encoding
= CUPS_US_ASCII
;
652 for (i
= 0; i
< (sizeof(lang_encodings
) / sizeof(lang_encodings
[0])); i
++)
653 if (strcmp(lang_encodings
[i
], line
) == 0)
655 lang
->encoding
= (cups_encoding_t
)i
;
661 * Read the strings from the file...
664 msg
= (cups_msg_t
)-1;
670 * Read a line from memory or from a file...
675 if (lang_default
[count
] == NULL
)
678 strlcpy(line
, lang_default
[count
], sizeof(line
));
680 else if (fgets(line
, sizeof(line
), fp
) == NULL
)
686 * Ignore blank lines...
689 i
= strlen(line
) - 1;
691 line
[i
] = '\0'; /* Strip LF */
697 * Grab the message number and text...
700 if (isdigit(line
[0] & 255))
701 msg
= (cups_msg_t
)atoi(line
);
705 if (msg
< 0 || msg
>= CUPS_MSG_MAX
)
709 while (isdigit(*text
& 255))
711 while (isspace(*text
& 255))
714 lang
->messages
[msg
] = strdup(text
);
718 * Close the file and return...
729 * '_cupsRestoreLocale()' - Restore the original locale...
733 _cupsRestoreLocale(int category
, /* I - Category */
734 char *oldlocale
) /* I - Old locale or NULL */
736 DEBUG_printf(("_cupsRestoreLocale(category=%d, oldlocale=\"%s\")\n",
737 category
, oldlocale
));
742 * Reset the locale and free the locale string...
745 setlocale(category
, oldlocale
);
752 * '_cupsSaveLocale()' - Set the locale and save a copy of the old locale...
755 char * /* O - Old locale or NULL */
756 _cupsSaveLocale(int category
, /* I - Category */
757 const char *locale
) /* I - New locale or NULL */
759 char *oldlocale
; /* Old locale */
762 DEBUG_printf(("_cupsSaveLocale(category=%d, locale=\"%s\")\n",
766 * Get the old locale and copy it...
769 if ((oldlocale
= setlocale(category
, NULL
)) != NULL
)
770 oldlocale
= strdup(oldlocale
);
772 DEBUG_printf((" oldlocale=\"%s\"\n", oldlocale
? oldlocale
: "(null)"));
775 * Set the new locale...
778 setlocale(category
, locale
);
781 * Return a copy of the old locale...
790 * Code & data to translate OSX's language names to their ISO 639-1 locale.
792 * The first version uses the new CoreFoundation API added in 10.3 (Panther),
793 * the second is for 10.2 (Jaguar).
796 # ifdef HAVE_CF_LOCALE_ID
798 * 'appleLangDefault()' - Get the default locale string.
801 static const char * /* O - Locale string */
802 appleLangDefault(void)
804 CFPropertyListRef localizationList
;
805 /* List of localization data */
806 CFStringRef languageName
; /* Current name */
807 CFStringRef localeName
; /* Canonical from of name */
808 static char language
[32] = "";
809 /* Cached language */
813 * Only do the lookup and translation the first time.
819 CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
820 kCFPreferencesCurrentApplication
);
822 if (localizationList
!= NULL
)
824 if (CFGetTypeID(localizationList
) == CFArrayGetTypeID() &&
825 CFArrayGetCount(localizationList
) > 0)
827 languageName
= CFArrayGetValueAtIndex(localizationList
, 0);
829 if (languageName
!= NULL
&&
830 CFGetTypeID(languageName
) == CFStringGetTypeID())
832 localeName
= CFLocaleCreateCanonicalLocaleIdentifierFromString(
833 kCFAllocatorDefault
, languageName
);
835 if (localeName
!= NULL
)
837 CFStringGetCString(localeName
, language
, sizeof(language
),
838 kCFStringEncodingASCII
);
839 CFRelease(localeName
);
841 if (!strcmp(language
, "en"))
842 strlcpy(language
, "en_US.UTF-8", sizeof(language
));
843 else if (strchr(language
, '.') == NULL
)
844 strlcat(language
, ".UTF-8", sizeof(language
));
849 CFRelease(localizationList
);
853 * If we didn't find the language, default to en_US...
857 strlcpy(language
, "en_US.UTF-8", sizeof(language
));
861 * Return the cached locale...
868 * Code & data to translate OSX 10.2's language names to their ISO 639-1
874 const char * const name
; /* Language name */
875 const char * const locale
; /* Locale name */
876 } apple_name_locale_t
;
878 static const apple_name_locale_t apple_name_locale
[] =
880 { "English" , "en_US.UTF-8" }, { "French" , "fr.UTF-8" },
881 { "German" , "de.UTF-8" }, { "Italian" , "it.UTF-8" },
882 { "Dutch" , "nl.UTF-8" }, { "Swedish" , "sv.UTF-8" },
883 { "Spanish" , "es.UTF-8" }, { "Danish" , "da.UTF-8" },
884 { "Portuguese" , "pt.UTF-8" }, { "Norwegian" , "no.UTF-8" },
885 { "Hebrew" , "he.UTF-8" }, { "Japanese" , "ja.UTF-8" },
886 { "Arabic" , "ar.UTF-8" }, { "Finnish" , "fi.UTF-8" },
887 { "Greek" , "el.UTF-8" }, { "Icelandic" , "is.UTF-8" },
888 { "Maltese" , "mt.UTF-8" }, { "Turkish" , "tr.UTF-8" },
889 { "Croatian" , "hr.UTF-8" }, { "Chinese" , "zh.UTF-8" },
890 { "Urdu" , "ur.UTF-8" }, { "Hindi" , "hi.UTF-8" },
891 { "Thai" , "th.UTF-8" }, { "Korean" , "ko.UTF-8" },
892 { "Lithuanian" , "lt.UTF-8" }, { "Polish" , "pl.UTF-8" },
893 { "Hungarian" , "hu.UTF-8" }, { "Estonian" , "et.UTF-8" },
894 { "Latvian" , "lv.UTF-8" }, { "Sami" , "se.UTF-8" },
895 { "Faroese" , "fo.UTF-8" }, { "Farsi" , "fa.UTF-8" },
896 { "Russian" , "ru.UTF-8" }, { "Chinese" , "zh.UTF-8" },
897 { "Dutch" , "nl.UTF-8" }, { "Irish" , "ga.UTF-8" },
898 { "Albanian" , "sq.UTF-8" }, { "Romanian" , "ro.UTF-8" },
899 { "Czech" , "cs.UTF-8" }, { "Slovak" , "sk.UTF-8" },
900 { "Slovenian" , "sl.UTF-8" }, { "Yiddish" , "yi.UTF-8" },
901 { "Serbian" , "sr.UTF-8" }, { "Macedonian" , "mk.UTF-8" },
902 { "Bulgarian" , "bg.UTF-8" }, { "Ukrainian" , "uk.UTF-8" },
903 { "Byelorussian", "be.UTF-8" }, { "Uzbek" , "uz.UTF-8" },
904 { "Kazakh" , "kk.UTF-8" }, { "Azerbaijani", "az.UTF-8" },
905 { "Azerbaijani" , "az.UTF-8" }, { "Armenian" , "hy.UTF-8" },
906 { "Georgian" , "ka.UTF-8" }, { "Moldavian" , "mo.UTF-8" },
907 { "Kirghiz" , "ky.UTF-8" }, { "Tajiki" , "tg.UTF-8" },
908 { "Turkmen" , "tk.UTF-8" }, { "Mongolian" , "mn.UTF-8" },
909 { "Mongolian" , "mn.UTF-8" }, { "Pashto" , "ps.UTF-8" },
910 { "Kurdish" , "ku.UTF-8" }, { "Kashmiri" , "ks.UTF-8" },
911 { "Sindhi" , "sd.UTF-8" }, { "Tibetan" , "bo.UTF-8" },
912 { "Nepali" , "ne.UTF-8" }, { "Sanskrit" , "sa.UTF-8" },
913 { "Marathi" , "mr.UTF-8" }, { "Bengali" , "bn.UTF-8" },
914 { "Assamese" , "as.UTF-8" }, { "Gujarati" , "gu.UTF-8" },
915 { "Punjabi" , "pa.UTF-8" }, { "Oriya" , "or.UTF-8" },
916 { "Malayalam" , "ml.UTF-8" }, { "Kannada" , "kn.UTF-8" },
917 { "Tamil" , "ta.UTF-8" }, { "Telugu" , "te.UTF-8" },
918 { "Sinhalese" , "si.UTF-8" }, { "Burmese" , "my.UTF-8" },
919 { "Khmer" , "km.UTF-8" }, { "Lao" , "lo.UTF-8" },
920 { "Vietnamese" , "vi.UTF-8" }, { "Indonesian" , "id.UTF-8" },
921 { "Tagalog" , "tl.UTF-8" }, { "Malay" , "ms.UTF-8" },
922 { "Malay" , "ms.UTF-8" }, { "Amharic" , "am.UTF-8" },
923 { "Tigrinya" , "ti.UTF-8" }, { "Oromo" , "om.UTF-8" },
924 { "Somali" , "so.UTF-8" }, { "Swahili" , "sw.UTF-8" },
925 { "Kinyarwanda" , "rw.UTF-8" }, { "Rundi" , "rn.UTF-8" },
926 { "Nyanja" , "" }, { "Malagasy" , "mg.UTF-8" },
927 { "Esperanto" , "eo.UTF-8" }, { "Welsh" , "cy.UTF-8" },
928 { "Basque" , "eu.UTF-8" }, { "Catalan" , "ca.UTF-8" },
929 { "Latin" , "la.UTF-8" }, { "Quechua" , "qu.UTF-8" },
930 { "Guarani" , "gn.UTF-8" }, { "Aymara" , "ay.UTF-8" },
931 { "Tatar" , "tt.UTF-8" }, { "Uighur" , "ug.UTF-8" },
932 { "Dzongkha" , "dz.UTF-8" }, { "Javanese" , "jv.UTF-8" },
933 { "Sundanese" , "su.UTF-8" }, { "Galician" , "gl.UTF-8" },
934 { "Afrikaans" , "af.UTF-8" }, { "Breton" , "br.UTF-8" },
935 { "Inuktitut" , "iu.UTF-8" }, { "Scottish" , "gd.UTF-8" },
936 { "Manx" , "gv.UTF-8" }, { "Irish" , "ga.UTF-8" },
937 { "Tongan" , "to.UTF-8" }, { "Greek" , "el.UTF-8" },
938 { "Greenlandic" , "kl.UTF-8" }, { "Azerbaijani", "az.UTF-8" }
943 * 'appleLangDefault()' - Get the default locale string.
946 static const char * /* O - Locale string */
947 appleLangDefault(void)
949 int i
; /* Looping var */
950 CFPropertyListRef localizationList
;
951 /* List of localization data */
952 CFStringRef localizationName
;
954 char buff
[256]; /* Temporary buffer */
955 static const char *language
= NULL
;
956 /* Cached language */
960 * Only do the lookup and translation the first time.
963 if (language
== NULL
)
966 CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
967 kCFPreferencesCurrentApplication
);
969 if (localizationList
!= NULL
)
971 if (CFGetTypeID(localizationList
) == CFArrayGetTypeID() &&
972 CFArrayGetCount(localizationList
) > 0)
974 localizationName
= CFArrayGetValueAtIndex(localizationList
, 0);
976 if (localizationName
!= NULL
&&
977 CFGetTypeID(localizationName
) == CFStringGetTypeID())
979 CFIndex length
= CFStringGetLength(localizationName
);
981 if (length
<= sizeof(buff
) &&
982 CFStringGetCString(localizationName
, buff
, sizeof(buff
),
983 kCFStringEncodingASCII
))
985 buff
[sizeof(buff
) - 1] = '\0';
988 i
< sizeof(apple_name_locale
) / sizeof(apple_name_locale
[0]);
991 if (strcasecmp(buff
, apple_name_locale
[i
].name
) == 0)
993 language
= apple_name_locale
[i
].locale
;
1001 CFRelease(localizationList
);
1005 * If we didn't find the language, default to en_US...
1008 if (language
== NULL
)
1009 language
= apple_name_locale
[0].locale
;
1013 * Return the cached locale...
1018 # endif /* HAVE_CF_LOCALE_ID */
1019 #endif /* __APPLE__ */
1023 * 'cups_cache_lookup()' - Lookup a language in the cache...
1026 static cups_lang_t
* /* O - Language data or NULL */
1027 cups_cache_lookup(const char *name
,/* I - Name of locale */
1028 cups_encoding_t encoding
)
1029 /* I - Encoding of locale */
1031 cups_lang_t
*lang
; /* Current language */
1034 DEBUG_printf(("cups_cache_lookup(name=\"%s\", encoding=%d(%s))\n", name
,
1035 encoding
, encoding
== CUPS_AUTO_ENCODING
? "auto" :
1036 lang_encodings
[encoding
]));
1039 * Loop through the cache and return a match if found...
1042 for (lang
= lang_cache
; lang
!= NULL
; lang
= lang
->next
)
1044 DEBUG_printf(("cups_cache_lookup: lang=%p, language=\"%s\", encoding=%d(%s)\n",
1045 lang
, lang
->language
, lang
->encoding
,
1046 lang_encodings
[lang
->encoding
]));
1048 if (!strcmp(lang
->language
, name
) &&
1049 (encoding
== CUPS_AUTO_ENCODING
|| encoding
== lang
->encoding
))
1053 DEBUG_puts("cups_cache_lookup: returning match!");
1059 DEBUG_puts("cups_cache_lookup: returning NULL!");