--- X11-6.8.1/xc/lib/X11/lcFile.c.orig 2004-09-26 00:27:04.984369960 +0200 +++ X11-6.8.1/xc/lib/X11/lcFile.c 2004-09-26 00:29:50.926142976 +0200 @@ -80,6 +80,8 @@ #endif #endif #endif +#include +#include #define NUM_LOCALEDIR 64 @@ -389,6 +391,48 @@ #define LOCALE_ALIAS "locale.alias" #endif +/* To be translated: ISO-8859-.* => ISO8859-.* */ +static char * +canonCharmap(char *alias) +{ + static char canonIso[] = "ISO8859-xx"; + + if (strncmp(alias, "ISO-8859-", 9) != 0) return alias; + if (strlen(alias) > 9 + 2) return alias; + strcpy(&canonIso[8], &alias[9]); + return canonIso; +} + +/* Substitute aa_BB[.CC][@dd] with aa_BB.`locale charmap`[@dd] */ +static char * +appendCharset(const char *locale) +{ + char *oldLocale; + char *charmap; + char *dot, *at; + char *fullName; + + if (strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0) { + fullName = Xmalloc(strlen(locale) + 1); + strcpy(fullName, locale); + return fullName; + } + oldLocale = setlocale(LC_CTYPE, locale); + charmap = canonCharmap(nl_langinfo(CODESET)); + setlocale(LC_CTYPE, oldLocale); + dot = strchr(locale, '.'); + if (dot == NULL) dot = strchr(locale, '\0'); + at = strchr(dot, '@'); + if (at == NULL) at = strchr(dot, '\0'); + fullName = Xmalloc(strlen(locale) - (at-dot) + strlen(charmap) + 2); + memset(fullName, 0, strlen(locale) - (at-dot) + strlen(charmap) + 2); + strncpy(fullName, locale, dot-locale); + strcat(fullName, "."); + strcat(fullName, charmap); + strcat(fullName, at); + return fullName; +} + int _XlcResolveLocaleName( const char* lc_name, @@ -416,11 +460,14 @@ if (name == NULL) { /* vendor locale name == Xlocale name, no expansion of alias */ - pub->siname = Xmalloc (strlen (lc_name) + 1); - strcpy (pub->siname, lc_name); + tmp_siname = Xmalloc (strlen (lc_name) + 1); + strcpy (tmp_siname, lc_name); } else { - pub->siname = name; + tmp_siname = name; } + + pub->siname = appendCharset(tmp_siname); + Xfree(tmp_siname); sinamelen = strlen (pub->siname); if (sinamelen == 1 && pub->siname[0] == 'C') { @@ -499,16 +546,20 @@ } /* If name is not an alias, use lc_name for locale.dir search */ - if (name == NULL) - name = lc_name; + if (name == NULL) { + name = appendCharset(lc_name); + } else { + char *tmp_name = name; + name = appendCharset(tmp_name); + Xfree(tmp_name); + } /* look at locale.dir */ target_dir = args[i]; if (!target_dir) { /* something wrong */ - if (name != lc_name) - Xfree(name); + Xfree(name); continue; } if ((1 + (target_dir ? strlen (target_dir) : 0) + @@ -516,8 +567,7 @@ sprintf(buf, "%s/locale.dir", target_dir); target_name = resolve_name(name, buf, RtoL); } - if (name != lc_name) - Xfree(name); + Xfree(name); if (target_name != NULL) { char *p = 0; if ((p = strstr(target_name, "/XLC_LOCALE"))) { --- X11-6.8.1/xc/lib/X11/lcWrap.c.orig 2004-09-26 00:27:36.684550800 +0200 +++ X11-6.8.1/xc/lib/X11/lcWrap.c 2004-09-26 00:27:31.716306088 +0200 @@ -255,7 +255,18 @@ #endif if (name == NULL) { + /* Set locale from env before querying it */ + char *oldLocale = NULL; + name = setlocale(LC_CTYPE, ""); + if (name != NULL) { /* if NULL, locale is unsupported by glibc */ + oldLocale = Xmalloc(strlen(name) + 1); + strcpy(oldLocale, name); + } name = setlocale (LC_CTYPE, (char *)NULL); + if (oldLocale != NULL) { + setlocale(LC_CTYPE, oldLocale); + Xfree(oldLocale); + } #if !defined(X_LOCALE) /* * _XlMapOSLocaleName will return the same string or a substring