4700857: RFE: separating user locale and user interface locale

Reviewed-by: okutsu
This commit is contained in:
Naoto Sato 2010-08-31 11:27:10 -07:00
parent cd78cc6fdb
commit 6d2cb04013
36 changed files with 14681 additions and 6960 deletions

View File

@ -443,7 +443,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getTimeInstance()
{
return get(DEFAULT, 0, 1, Locale.getDefault());
return get(DEFAULT, 0, 1, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -455,7 +455,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getTimeInstance(int style)
{
return get(style, 0, 1, Locale.getDefault());
return get(style, 0, 1, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -479,7 +479,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getDateInstance()
{
return get(0, DEFAULT, 2, Locale.getDefault());
return get(0, DEFAULT, 2, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -491,7 +491,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getDateInstance(int style)
{
return get(0, style, 2, Locale.getDefault());
return get(0, style, 2, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -515,7 +515,7 @@ public abstract class DateFormat extends Format {
*/
public final static DateFormat getDateTimeInstance()
{
return get(DEFAULT, DEFAULT, 3, Locale.getDefault());
return get(DEFAULT, DEFAULT, 3, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -530,7 +530,7 @@ public abstract class DateFormat extends Format {
public final static DateFormat getDateTimeInstance(int dateStyle,
int timeStyle)
{
return get(timeStyle, dateStyle, 3, Locale.getDefault());
return get(timeStyle, dateStyle, 3, Locale.getDefault(Locale.Category.FORMAT));
}
/**

View File

@ -118,7 +118,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
*/
public DateFormatSymbols()
{
initializeData(Locale.getDefault());
initializeData(Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -282,7 +282,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* @since 1.6
*/
public static final DateFormatSymbols getInstance() {
return getInstance(Locale.getDefault());
return getInstance(Locale.getDefault(Locale.Category.FORMAT));
}
/**

View File

@ -392,7 +392,7 @@ public class DecimalFormat extends NumberFormat {
* @see java.text.NumberFormat#getPercentInstance
*/
public DecimalFormat() {
Locale def = Locale.getDefault();
Locale def = Locale.getDefault(Locale.Category.FORMAT);
// try to get the pattern from the cache
String pattern = (String) cachedLocaleData.get(def);
if (pattern == null) { /* cache miss */
@ -430,7 +430,7 @@ public class DecimalFormat extends NumberFormat {
*/
public DecimalFormat(String pattern) {
// Always applyPattern after the symbols are set
this.symbols = new DecimalFormatSymbols(Locale.getDefault());
this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
applyPattern(pattern, false);
}

View File

@ -76,7 +76,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* {@link #getInstance(Locale) getInstance} method.
*/
public DecimalFormatSymbols() {
initialize( Locale.getDefault() );
initialize( Locale.getDefault(Locale.Category.FORMAT) );
}
/**
@ -125,7 +125,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
* @since 1.6
*/
public static final DecimalFormatSymbols getInstance() {
return getInstance(Locale.getDefault());
return getInstance(Locale.getDefault(Locale.Category.FORMAT));
}
/**

View File

@ -363,7 +363,7 @@ public class MessageFormat extends Format {
* @exception IllegalArgumentException if the pattern is invalid
*/
public MessageFormat(String pattern) {
this.locale = Locale.getDefault();
this.locale = Locale.getDefault(Locale.Category.FORMAT);
applyPattern(pattern);
}

View File

@ -381,7 +381,7 @@ public abstract class NumberFormat extends Format {
* {@link #getNumberInstance() getNumberInstance()}.
*/
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(), NUMBERSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
/**
@ -397,7 +397,7 @@ public abstract class NumberFormat extends Format {
* Returns a general-purpose number format for the current default locale.
*/
public final static NumberFormat getNumberInstance() {
return getInstance(Locale.getDefault(), NUMBERSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
/**
@ -420,7 +420,7 @@ public abstract class NumberFormat extends Format {
* @since 1.4
*/
public final static NumberFormat getIntegerInstance() {
return getInstance(Locale.getDefault(), INTEGERSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
}
/**
@ -443,7 +443,7 @@ public abstract class NumberFormat extends Format {
* Returns a currency format for the current default locale.
*/
public final static NumberFormat getCurrencyInstance() {
return getInstance(Locale.getDefault(), CURRENCYSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
}
/**
@ -457,7 +457,7 @@ public abstract class NumberFormat extends Format {
* Returns a percentage format for the current default locale.
*/
public final static NumberFormat getPercentInstance() {
return getInstance(Locale.getDefault(), PERCENTSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
}
/**
@ -471,7 +471,7 @@ public abstract class NumberFormat extends Format {
* Returns a scientific format for the current default locale.
*/
/*public*/ final static NumberFormat getScientificInstance() {
return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
}
/**

View File

@ -474,7 +474,7 @@ public class SimpleDateFormat extends DateFormat {
* class.
*/
public SimpleDateFormat() {
this(SHORT, SHORT, Locale.getDefault());
this(SHORT, SHORT, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -490,7 +490,7 @@ public class SimpleDateFormat extends DateFormat {
*/
public SimpleDateFormat(String pattern)
{
this(pattern, Locale.getDefault());
this(pattern, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -535,7 +535,7 @@ public class SimpleDateFormat extends DateFormat {
this.pattern = pattern;
this.formatData = (DateFormatSymbols) formatSymbols.clone();
this.locale = Locale.getDefault();
this.locale = Locale.getDefault(Locale.Category.FORMAT);
initializeCalendar(this.locale);
initialize(this.locale);
useDateFormatSymbols = true;

View File

@ -933,7 +933,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
protected Calendar()
{
this(TimeZone.getDefaultRef(), Locale.getDefault());
this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
sharedZone = true;
}
@ -962,7 +962,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
public static Calendar getInstance()
{
Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
cal.sharedZone = true;
return cal;
}
@ -977,7 +977,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
*/
public static Calendar getInstance(TimeZone zone)
{
return createCalendar(zone, Locale.getDefault());
return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
}
/**

View File

@ -452,7 +452,7 @@ public final class Currency implements Serializable {
* @return the symbol of this currency for the default locale
*/
public String getSymbol() {
return getSymbol(Locale.getDefault());
return getSymbol(Locale.getDefault(Locale.Category.DISPLAY));
}
/**
@ -528,7 +528,7 @@ public final class Currency implements Serializable {
* @since 1.7
*/
public String getDisplayName() {
return getDisplayName(Locale.getDefault());
return getDisplayName(Locale.getDefault(Locale.Category.DISPLAY));
}
/**

View File

@ -1866,7 +1866,7 @@ public final class Formatter implements Closeable, Flushable {
* virtual machine.
*/
public Formatter() {
init(new StringBuilder(), Locale.getDefault());
init(new StringBuilder(), Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -1882,7 +1882,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(Appendable a) {
if (a == null)
a = new StringBuilder();
init(a, Locale.getDefault());
init(a, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -1949,7 +1949,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(String fileName) throws FileNotFoundException {
init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
Locale.getDefault());
Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -1985,7 +1985,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(String fileName, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{
this(fileName, csn, Locale.getDefault());
this(fileName, csn, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -2057,7 +2057,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(File file) throws FileNotFoundException {
init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
Locale.getDefault());
Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -2093,7 +2093,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(File file, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{
this(file, csn, Locale.getDefault());
this(file, csn, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -2152,7 +2152,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(PrintStream ps) {
if (ps == null)
throw new NullPointerException();
init((Appendable)ps, Locale.getDefault());
init((Appendable)ps, Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -2171,7 +2171,7 @@ public final class Formatter implements Closeable, Flushable {
*/
public Formatter(OutputStream os) {
init(new BufferedWriter(new OutputStreamWriter(os)),
Locale.getDefault());
Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -2195,7 +2195,7 @@ public final class Formatter implements Closeable, Flushable {
public Formatter(OutputStream os, String csn)
throws UnsupportedEncodingException
{
this(os, csn, Locale.getDefault());
this(os, csn, Locale.getDefault(Locale.Category.FORMAT));
}
/**

View File

@ -555,7 +555,7 @@ public class GregorianCalendar extends Calendar {
* in the default time zone with the default locale.
*/
public GregorianCalendar() {
this(TimeZone.getDefaultRef(), Locale.getDefault());
this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
setZoneShared(true);
}
@ -566,7 +566,7 @@ public class GregorianCalendar extends Calendar {
* @param zone the given time zone.
*/
public GregorianCalendar(TimeZone zone) {
this(zone, Locale.getDefault());
this(zone, Locale.getDefault(Locale.Category.FORMAT));
}
/**

View File

@ -395,33 +395,105 @@ public final class Locale implements Cloneable, Serializable {
// do not synchronize this method - see 4071298
// it's OK if more than one default locale happens to be created
if (defaultLocale == null) {
String language, region, country, variant;
language = AccessController.doPrivileged(
new GetPropertyAction("user.language", "en"));
// for compatibility, check for old user.region property
region = AccessController.doPrivileged(
new GetPropertyAction("user.region"));
if (region != null) {
// region can be of form country, country_variant, or _variant
int i = region.indexOf('_');
if (i >= 0) {
country = region.substring(0, i);
variant = region.substring(i + 1);
} else {
country = region;
variant = "";
}
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant", ""));
}
defaultLocale = getInstance(language, country, variant);
initDefault();
}
return defaultLocale;
}
/**
* Gets the current value of the default locale for the specified Category
* for this instance of the Java Virtual Machine.
* <p>
* The Java Virtual Machine sets the default locale during startup based
* on the host environment. It is used by many locale-sensitive methods
* if no locale is explicitly specified. It can be changed using the
* setDefault(Locale.Category, Locale) method.
*
* @param category - the specified category to get the default locale
* @throws NullPointerException - if category is null
* @return the default locale for the specified Category for this instance
* of the Java Virtual Machine
* @see #setDefault(Locale.Category, Locale)
* @since 1.7
*/
public static Locale getDefault(Locale.Category category) {
// do not synchronize this method - see 4071298
// it's OK if more than one default locale happens to be created
switch (category) {
case DISPLAY:
if (defaultDisplayLocale == null) {
initDefault(category);
}
return defaultDisplayLocale;
case FORMAT:
if (defaultFormatLocale == null) {
initDefault(category);
}
return defaultFormatLocale;
default:
assert false: "Unknown Category";
}
return getDefault();
}
private static void initDefault() {
String language, region, country, variant;
language = AccessController.doPrivileged(
new GetPropertyAction("user.language", "en"));
// for compatibility, check for old user.region property
region = AccessController.doPrivileged(
new GetPropertyAction("user.region"));
if (region != null) {
// region can be of form country, country_variant, or _variant
int i = region.indexOf('_');
if (i >= 0) {
country = region.substring(0, i);
variant = region.substring(i + 1);
} else {
country = region;
variant = "";
}
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant", ""));
}
defaultLocale = getInstance(language, country, variant);
}
private static void initDefault(Locale.Category category) {
String language, region, country, variant;
switch (category) {
case DISPLAY:
language = AccessController.doPrivileged(
new GetPropertyAction("user.language.display", ""));
if ("".equals(language)) {
defaultDisplayLocale = getDefault();
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country.display", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant.display", ""));
defaultDisplayLocale = getInstance(language, country, variant);
}
break;
case FORMAT:
language = AccessController.doPrivileged(
new GetPropertyAction("user.language.format", ""));
if ("".equals(language)) {
defaultFormatLocale = getDefault();
} else {
country = AccessController.doPrivileged(
new GetPropertyAction("user.country.format", ""));
variant = AccessController.doPrivileged(
new GetPropertyAction("user.variant.format", ""));
defaultFormatLocale = getInstance(language, country, variant);
}
break;
}
}
/**
* Sets the default locale for this instance of the Java Virtual Machine.
* This does not affect the host locale.
@ -438,6 +510,9 @@ public final class Locale implements Cloneable, Serializable {
* of functionality, this method should only be used if the caller
* is prepared to reinitialize locale-sensitive code running
* within the same Java Virtual Machine.
* <p>
* By setting the default locale with this method, all of the default
* locales for each Category are also set to the specified default locale.
*
* @throws SecurityException
* if a security manager exists and its
@ -448,13 +523,59 @@ public final class Locale implements Cloneable, Serializable {
* @see java.util.PropertyPermission
*/
public static synchronized void setDefault(Locale newLocale) {
setDefault(Category.DISPLAY, newLocale);
setDefault(Category.FORMAT, newLocale);
defaultLocale = newLocale;
}
/**
* Sets the default locale for the specified Category for this instance
* of the Java Virtual Machine. This does not affect the host locale.
* <p>
* If there is a security manager, its checkPermission method is called
* with a PropertyPermission("user.language", "write") permission before
* the default locale is changed.
* <p>
* The Java Virtual Machine sets the default locale during startup based
* on the host environment. It is used by many locale-sensitive methods
* if no locale is explicitly specified.
* <p>
* Since changing the default locale may affect many different areas of
* functionality, this method should only be used if the caller is
* prepared to reinitialize locale-sensitive code running within the
* same Java Virtual Machine.
* <p>
*
* @param category - the specified category to set the default locale
* @param newLocale - the new default locale
* @throws SecurityException - if a security manager exists and its
* checkPermission method doesn't allow the operation.
* @throws NullPointerException - if category and/or newLocale is null
* @see SecurityManager.checkPermission(java.security.Permission)
* @see PropertyPermission
* @see #getDefault(Locale.Category)
* @since 1.7
*/
public static synchronized void setDefault(Locale.Category category,
Locale newLocale) {
if (category == null)
throw new NullPointerException("Category cannot be NULL");
if (newLocale == null)
throw new NullPointerException("Can't set default locale to NULL");
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(new PropertyPermission
("user.language", "write"));
defaultLocale = newLocale;
switch (category) {
case DISPLAY:
defaultDisplayLocale = newLocale;
break;
case FORMAT:
defaultFormatLocale = newLocale;
break;
default:
assert false: "Unknown Category";
}
}
/**
@ -642,7 +763,7 @@ public final class Locale implements Cloneable, Serializable {
* value. If the locale doesn't specify a language, this function returns the empty string.
*/
public final String getDisplayLanguage() {
return getDisplayLanguage(getDefault());
return getDisplayLanguage(getDefault(Category.DISPLAY));
}
/**
@ -677,7 +798,7 @@ public final class Locale implements Cloneable, Serializable {
* value. If the locale doesn't specify a country, this function returns the empty string.
*/
public final String getDisplayCountry() {
return getDisplayCountry(getDefault());
return getDisplayCountry(getDefault(Category.DISPLAY));
}
/**
@ -744,7 +865,7 @@ public final class Locale implements Cloneable, Serializable {
* doesn't specify a variant code, this function returns the empty string.
*/
public final String getDisplayVariant() {
return getDisplayVariant(getDefault());
return getDisplayVariant(getDefault(Category.DISPLAY));
}
/**
@ -790,7 +911,7 @@ public final class Locale implements Cloneable, Serializable {
* and variant fields are all empty, this function returns the empty string.
*/
public final String getDisplayName() {
return getDisplayName(getDefault());
return getDisplayName(getDefault(Category.DISPLAY));
}
/**
@ -970,6 +1091,8 @@ public final class Locale implements Cloneable, Serializable {
private transient volatile int hashCodeValue = 0;
private static Locale defaultLocale = null;
private static Locale defaultDisplayLocale = null;
private static Locale defaultFormatLocale = null;
/**
* Return an array of the display names of the variant.
@ -1140,4 +1263,28 @@ public final class Locale implements Cloneable, Serializable {
return null;
}
}
/**
* Enum for locale categories. These locale categories are used to get/set
* the default locale for the specific functionality represented by the
* category.
*
* @see #getDefault(Locale.Category)
* @see #setDefault(Locale.Category, Locale)
* @since 1.7
*/
public enum Category {
/**
* Category used to represent the default locale for
* displaying user interfaces.
*/
DISPLAY,
/**
* Category used to represent the default locale for
* formatting dates, numbers, and/or currencies.
*/
FORMAT,
}
}

View File

@ -582,7 +582,7 @@ public final class Scanner implements Iterator<String>, Closeable {
matcher = delimPattern.matcher(buf);
matcher.useTransparentBounds(true);
matcher.useAnchoringBounds(false);
useLocale(Locale.getDefault());
useLocale(Locale.getDefault(Locale.Category.FORMAT));
}
/**
@ -2642,7 +2642,7 @@ public final class Scanner implements Iterator<String>, Closeable {
*/
public Scanner reset() {
delimPattern = WHITESPACE_PATTERN;
useLocale(Locale.getDefault());
useLocale(Locale.getDefault(Locale.Category.FORMAT));
useRadix(10);
clearCaches();
return this;

View File

@ -312,7 +312,7 @@ abstract public class TimeZone implements Serializable, Cloneable {
* @since 1.2
*/
public final String getDisplayName() {
return getDisplayName(false, LONG, Locale.getDefault());
return getDisplayName(false, LONG, Locale.getDefault(Locale.Category.DISPLAY));
}
/**
@ -342,7 +342,7 @@ abstract public class TimeZone implements Serializable, Cloneable {
* @since 1.2
*/
public final String getDisplayName(boolean daylight, int style) {
return getDisplayName(daylight, style, Locale.getDefault());
return getDisplayName(daylight, style, Locale.getDefault(Locale.Category.DISPLAY));
}
/**

View File

@ -80,6 +80,21 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
(*env)->DeleteLocalRef(env, jval); \
(*env)->DeleteLocalRef(env, r); \
} else ((void) 0)
#define REMOVEPROP(props, key) \
if (1) { \
jstring jkey = JNU_NewStringPlatform(env, key); \
jobject r = (*env)->CallObjectMethod(env, props, removeID, jkey); \
if ((*env)->ExceptionOccurred(env)) return NULL; \
(*env)->DeleteLocalRef(env, jkey); \
(*env)->DeleteLocalRef(env, r); \
} else ((void) 0)
#define GETPROP(props, key, jret) \
if (1) { \
jstring jkey = JNU_NewStringPlatform(env, key); \
jret = (*env)->CallObjectMethod(env, props, getPropID, jkey); \
if ((*env)->ExceptionOccurred(env)) return NULL; \
(*env)->DeleteLocalRef(env, jkey); \
} else ((void) 0)
#ifndef VENDOR /* Third party may overwrite this. */
#define VENDOR "Sun Microsystems Inc."
@ -90,6 +105,60 @@ Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)
#define JAVA_MAX_SUPPORTED_VERSION 51
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
static int fmtdefault; // boolean value
jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
char *platformDispVal, char *platformFmtVal,
jmethodID putID, jmethodID getPropID) {
jstring jVMBaseVal = NULL;
GETPROP(props, baseKey, jVMBaseVal);
if (jVMBaseVal) {
// user specified the base property. there's nothing to do here.
(*env)->DeleteLocalRef(env, jVMBaseVal);
} else {
char buf[64];
jstring jVMVal = NULL;
const char *baseVal = "";
/* user.xxx base property */
if (fmtdefault) {
if (platformFmtVal) {
PUTPROP(props, baseKey, platformFmtVal);
baseVal = platformFmtVal;
}
} else {
if (platformDispVal) {
PUTPROP(props, baseKey, platformDispVal);
baseVal = platformDispVal;
}
}
/* user.xxx.display property */
jio_snprintf(buf, sizeof(buf), "%s.display", baseKey);
GETPROP(props, buf, jVMVal);
if (jVMVal == NULL) {
if (platformDispVal && (strcmp(baseVal, platformDispVal) != 0)) {
PUTPROP(props, buf, platformDispVal);
}
} else {
(*env)->DeleteLocalRef(env, jVMVal);
}
/* user.xxx.format property */
jio_snprintf(buf, sizeof(buf), "%s.format", baseKey);
GETPROP(props, buf, jVMVal);
if (jVMVal == NULL) {
if (platformFmtVal && (strcmp(baseVal, platformFmtVal) != 0)) {
PUTPROP(props, buf, platformFmtVal);
}
} else {
(*env)->DeleteLocalRef(env, jVMVal);
}
}
return NULL;
}
JNIEXPORT jobject JNICALL
Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
{
@ -99,6 +168,16 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
(*env)->GetObjectClass(env, props),
"put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
jmethodID removeID = (*env)->GetMethodID(env,
(*env)->GetObjectClass(env, props),
"remove",
"(Ljava/lang/Object;)Ljava/lang/Object;");
jmethodID getPropID = (*env)->GetMethodID(env,
(*env)->GetObjectClass(env, props),
"getProperty",
"(Ljava/lang/String;)Ljava/lang/String;");
jobject ret = NULL;
jstring jVMVal = NULL;
if (sprops == NULL || putID == NULL ) return NULL;
@ -218,7 +297,46 @@ Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)
PUTPROP(props, "sun.desktop", sprops->desktop);
}
return JVM_InitProperties(env, props);
/*
* unset "user.language", "user.country", and "user.variant"
* in order to tell whether the command line option "-DXXXX=YYYY" is
* specified or not. They will be reset in fillI18nProps() below.
*/
REMOVEPROP(props, "user.language");
REMOVEPROP(props, "user.country");
REMOVEPROP(props, "user.variant");
REMOVEPROP(props, "file.encoding");
ret = JVM_InitProperties(env, props);
/* Check the compatibility flag */
GETPROP(props, "sun.locale.formatasdefault", jVMVal);
if (jVMVal) {
const char * val = (*env)->GetStringUTFChars(env, jVMVal, 0);
fmtdefault = !strcmp(val, "true");
(*env)->ReleaseStringUTFChars(env, jVMVal, val);
(*env)->DeleteLocalRef(env, jVMVal);
}
/* reconstruct i18n related properties */
fillI18nProps(env, props, "user.language", sprops->display_language,
sprops->format_language, putID, getPropID);
fillI18nProps(env, props, "user.country",
sprops->display_country, sprops->format_country, putID, getPropID);
fillI18nProps(env, props, "user.variant",
sprops->display_variant, sprops->format_variant, putID, getPropID);
GETPROP(props, "file.encoding", jVMVal);
if (jVMVal == NULL) {
if (fmtdefault) {
PUTPROP(props, "file.encoding", sprops->encoding);
} else {
PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
}
} else {
(*env)->DeleteLocalRef(env, jVMVal);
}
return ret;
}
/*

View File

@ -53,8 +53,14 @@ typedef struct {
nchar *user_home;
char *language;
char *format_language;
char *display_language;
char *country;
char *format_country;
char *display_country;
char *variant;
char *format_variant;
char *display_variant;
char *encoding;
char *sun_jnu_encoding;
char *timezone;

View File

@ -115,6 +115,174 @@ setPathEnvironment(char *envstring)
#define P_tmpdir "/var/tmp"
#endif
static int ParseLocale(int cat, char ** std_language, char ** std_country, char ** std_variant, char ** std_encoding) {
char temp[64];
char *language = NULL, *country = NULL, *variant = NULL,
*encoding = NULL;
char *p, encoding_variant[64];
char *lc;
/* Query the locale set for the category */
lc = setlocale(cat, NULL);
#ifndef __linux__
if (lc == NULL) {
return 0;
}
if (cat == LC_CTYPE) {
/*
* Workaround for Solaris bug 4201684: Xlib doesn't like @euro
* locales. Since we don't depend on the libc @euro behavior,
* we just remove the qualifier.
* On Linux, the bug doesn't occur; on the other hand, @euro
* is needed there because it's a shortcut that also determines
* the encoding - without it, we wouldn't get ISO-8859-15.
* Therefore, this code section is Solaris-specific.
*/
lc = strdup(lc); /* keep a copy, setlocale trashes original. */
strcpy(temp, lc);
p = strstr(temp, "@euro");
if (p != NULL) {
*p = '\0';
setlocale(LC_ALL, temp);
}
}
#else
if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
lc = "en_US";
}
#endif
/*
* locale string format in Solaris is
* <language name>_<country name>.<encoding name>@<variant name>
* <country name>, <encoding name>, and <variant name> are optional.
*/
strcpy(temp, lc);
/* Parse the language, country, encoding, and variant from the
* locale. Any of the elements may be missing, but they must occur
* in the order language_country.encoding@variant, and must be
* preceded by their delimiter (except for language).
*
* If the locale name (without .encoding@variant, if any) matches
* any of the names in the locale_aliases list, map it to the
* corresponding full locale name. Most of the entries in the
* locale_aliases list are locales that include a language name but
* no country name, and this facility is used to map each language
* to a default country if that's possible. It's also used to map
* the Solaris locale aliases to their proper Java locale IDs.
*/
if ((p = strchr(temp, '.')) != NULL) {
strcpy(encoding_variant, p); /* Copy the leading '.' */
*p = '\0';
} else if ((p = strchr(temp, '@')) != NULL) {
strcpy(encoding_variant, p); /* Copy the leading '@' */
*p = '\0';
} else {
*encoding_variant = '\0';
}
if (mapLookup(locale_aliases, temp, &p)) {
strcpy(temp, p);
}
language = temp;
if ((country = strchr(temp, '_')) != NULL) {
*country++ = '\0';
}
p = encoding_variant;
if ((encoding = strchr(p, '.')) != NULL) {
p[encoding++ - p] = '\0';
p = encoding;
}
if ((variant = strchr(p, '@')) != NULL) {
p[variant++ - p] = '\0';
}
/* Normalize the language name */
if (std_language != NULL) {
*std_language = "en";
if (language != NULL) {
mapLookup(language_names, language, std_language);
}
}
/* Normalize the country name */
if (std_country != NULL && country != NULL) {
*std_country = country;
mapLookup(country_names, country, std_country);
}
/* Normalize the variant name. Note that we only use
* variants listed in the mapping array; others are ignored. */
if (std_variant != NULL && variant != NULL) {
mapLookup(variant_names, variant, std_variant);
}
/* Normalize the encoding name. Note that we IGNORE the string
* 'encoding' extracted from the locale name above. Instead, we use the
* more reliable method of calling nl_langinfo(CODESET). This function
* returns an empty string if no encoding is set for the given locale
* (e.g., the C or POSIX locales); we use the default ISO 8859-1
* converter for such locales.
*/
if (std_encoding != NULL) {
/* OK, not so reliable - nl_langinfo() gives wrong answers on
* Euro locales, in particular. */
if (strcmp(p, "ISO8859-15") == 0)
p = "ISO8859-15";
else
p = nl_langinfo(CODESET);
/* Convert the bare "646" used on Solaris to a proper IANA name */
if (strcmp(p, "646") == 0)
p = "ISO646-US";
/* return same result nl_langinfo would return for en_UK,
* in order to use optimizations. */
*std_encoding = (*p != '\0') ? p : "ISO8859-1";
#ifdef __linux__
/*
* Remap the encoding string to a different value for japanese
* locales on linux so that customized converters are used instead
* of the default converter for "EUC-JP". The customized converters
* omit support for the JIS0212 encoding which is not supported by
* the variant of "EUC-JP" encoding used on linux
*/
if (strcmp(p, "EUC-JP") == 0) {
*std_encoding = "EUC-JP-LINUX";
}
#else
if (strcmp(p,"eucJP") == 0) {
/* For Solaris use customized vendor defined character
* customized EUC-JP converter
*/
*std_encoding = "eucJP-open";
} else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
/*
* Remap the encoding string to Big5_Solaris which augments
* the default converter for Solaris Big5 locales to include
* seven additional ideographic characters beyond those included
* in the Java "Big5" converter.
*/
*std_encoding = "Big5_Solaris";
} else if (strcmp(p, "Big5-HKSCS") == 0) {
/*
* Solaris uses HKSCS2001
*/
*std_encoding = "Big5-HKSCS-2001";
}
#endif
}
return 1;
}
/* This function gets called very early, before VM_CALLS are setup.
* Do not use any of the VM_CALLS entries!!!
*/
@ -185,182 +353,25 @@ GetJavaProperties(JNIEnv *env)
/* Determine the language, country, variant, and encoding from the host,
* and store these in the user.language, user.country, user.variant and
* file.encoding system properties. */
{
char *lc;
lc = setlocale(LC_CTYPE, "");
#ifndef __linux__
if (lc == NULL) {
/*
* 'lc == null' means system doesn't support user's environment
* variable's locale.
*/
setlocale(LC_ALL, "C");
sprops.language = "en";
sprops.encoding = "ISO8859-1";
sprops.sun_jnu_encoding = sprops.encoding;
} else {
#else
if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
lc = "en_US";
}
{
#endif
/*
* locale string format in Solaris is
* <language name>_<country name>.<encoding name>@<variant name>
* <country name>, <encoding name>, and <variant name> are optional.
*/
char temp[64];
char *language = NULL, *country = NULL, *variant = NULL,
*encoding = NULL;
char *std_language = NULL, *std_country = NULL, *std_variant = NULL,
*std_encoding = NULL;
char *p, encoding_variant[64];
int i, found;
#ifndef __linux__
/*
* Workaround for Solaris bug 4201684: Xlib doesn't like @euro
* locales. Since we don't depend on the libc @euro behavior,
* we just remove the qualifier.
* On Linux, the bug doesn't occur; on the other hand, @euro
* is needed there because it's a shortcut that also determines
* the encoding - without it, we wouldn't get ISO-8859-15.
* Therefore, this code section is Solaris-specific.
*/
lc = strdup(lc); /* keep a copy, setlocale trashes original. */
strcpy(temp, lc);
p = strstr(temp, "@euro");
if (p != NULL)
*p = '\0';
setlocale(LC_ALL, temp);
#endif
strcpy(temp, lc);
/* Parse the language, country, encoding, and variant from the
* locale. Any of the elements may be missing, but they must occur
* in the order language_country.encoding@variant, and must be
* preceded by their delimiter (except for language).
*
* If the locale name (without .encoding@variant, if any) matches
* any of the names in the locale_aliases list, map it to the
* corresponding full locale name. Most of the entries in the
* locale_aliases list are locales that include a language name but
* no country name, and this facility is used to map each language
* to a default country if that's possible. It's also used to map
* the Solaris locale aliases to their proper Java locale IDs.
*/
if ((p = strchr(temp, '.')) != NULL) {
strcpy(encoding_variant, p); /* Copy the leading '.' */
*p = '\0';
} else if ((p = strchr(temp, '@')) != NULL) {
strcpy(encoding_variant, p); /* Copy the leading '@' */
*p = '\0';
} else {
*encoding_variant = '\0';
}
if (mapLookup(locale_aliases, temp, &p)) {
strcpy(temp, p);
}
language = temp;
if ((country = strchr(temp, '_')) != NULL) {
*country++ = '\0';
}
p = encoding_variant;
if ((encoding = strchr(p, '.')) != NULL) {
p[encoding++ - p] = '\0';
p = encoding;
}
if ((variant = strchr(p, '@')) != NULL) {
p[variant++ - p] = '\0';
}
/* Normalize the language name */
std_language = "en";
if (language != NULL) {
mapLookup(language_names, language, &std_language);
}
sprops.language = std_language;
/* Normalize the country name */
if (country != NULL) {
std_country = country;
mapLookup(country_names, country, &std_country);
sprops.country = strdup(std_country);
}
/* Normalize the variant name. Note that we only use
* variants listed in the mapping array; others are ignored. */
if (variant != NULL) {
mapLookup(variant_names, variant, &std_variant);
sprops.variant = std_variant;
}
/* Normalize the encoding name. Note that we IGNORE the string
* 'encoding' extracted from the locale name above. Instead, we use the
* more reliable method of calling nl_langinfo(CODESET). This function
* returns an empty string if no encoding is set for the given locale
* (e.g., the C or POSIX locales); we use the default ISO 8859-1
* converter for such locales.
*/
/* OK, not so reliable - nl_langinfo() gives wrong answers on
* Euro locales, in particular. */
if (strcmp(p, "ISO8859-15") == 0)
p = "ISO8859-15";
else
p = nl_langinfo(CODESET);
/* Convert the bare "646" used on Solaris to a proper IANA name */
if (strcmp(p, "646") == 0)
p = "ISO646-US";
/* return same result nl_langinfo would return for en_UK,
* in order to use optimizations. */
std_encoding = (*p != '\0') ? p : "ISO8859-1";
#ifdef __linux__
/*
* Remap the encoding string to a different value for japanese
* locales on linux so that customized converters are used instead
* of the default converter for "EUC-JP". The customized converters
* omit support for the JIS0212 encoding which is not supported by
* the variant of "EUC-JP" encoding used on linux
*/
if (strcmp(p, "EUC-JP") == 0) {
std_encoding = "EUC-JP-LINUX";
}
#else
if (strcmp(p,"eucJP") == 0) {
/* For Solaris use customized vendor defined character
* customized EUC-JP converter
*/
std_encoding = "eucJP-open";
} else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {
/*
* Remap the encoding string to Big5_Solaris which augments
* the default converter for Solaris Big5 locales to include
* seven additional ideographic characters beyond those included
* in the Java "Big5" converter.
*/
std_encoding = "Big5_Solaris";
} else if (strcmp(p, "Big5-HKSCS") == 0) {
/*
* Solaris uses HKSCS2001
*/
std_encoding = "Big5-HKSCS-2001";
}
#endif
sprops.encoding = std_encoding;
sprops.sun_jnu_encoding = sprops.encoding;
}
setlocale(LC_ALL, "");
if (ParseLocale(LC_CTYPE,
&(sprops.format_language),
&(sprops.format_country),
&(sprops.format_variant),
&(sprops.encoding))) {
ParseLocale(LC_MESSAGES,
&(sprops.language),
&(sprops.country),
&(sprops.variant),
NULL);
} else {
sprops.language = "en";
sprops.encoding = "ISO8859-1";
}
sprops.display_language = sprops.language;
sprops.display_country = sprops.country;
sprops.display_variant = sprops.variant;
sprops.sun_jnu_encoding = sprops.encoding;
#ifdef __linux__
#if __BYTE_ORDER == __LITTLE_ENDIAN

View File

@ -43,413 +43,48 @@
#endif
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
static void SetupI18nProps(LCID lcid, char** language, char** country,
char** variant, char** encoding);
#define SHELL_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
/* Encodings for Windows language groups. According to
www.microsoft.com/globaldev/faqs/locales.asp,
some locales do not have codepages, and are
supported in Windows 2000/XP solely through Unicode.
In this case, we use utf-8 encoding */
static char *encoding_names[] = {
"Cp1250", /* 0:Latin 2 */
"Cp1251", /* 1:Cyrillic */
"Cp1252", /* 2:Latin 1 */
"Cp1253", /* 3:Greek */
"Cp1254", /* 4:Latin 5 */
"Cp1255", /* 5:Hebrew */
"Cp1256", /* 6:Arabic */
"Cp1257", /* 7:Baltic */
"Cp1258", /* 8:Viet Nam */
"MS874", /* 9:Thai */
"MS932", /* 10:Japanese */
"GBK", /* 11:PRC GBK */
"MS949", /* 12:Korean Extended Wansung */
"MS950", /* 13:Chinese (Taiwan, Hongkong, Macau) */
"utf-8", /* 14:Unicode */
"MS1361", /* 15:Korean Johab */
};
/*
* List mapping from LanguageID to Java locale IDs.
* The entries in this list should not be construed to suggest we actually have
* full locale-data and other support for all of these locales; these are
* merely all of the Windows locales for which we could construct an accurate
* locale ID. The data is based on the web page "Windows XP/Server 2003 -
* List of Locale IDs, Input Locale, and Language Collection"
* (http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx)
*
* Some of the language IDs below are not yet used by Windows, but were
* defined by Microsoft for other products, such as Office XP. They may
* become Windows language IDs in the future.
*
*/
typedef struct LANGIDtoLocale {
WORD langID;
WORD encoding;
char* javaID;
} LANGIDtoLocale;
static LANGIDtoLocale langIDMap[] = {
/* fallback locales to use when the country code doesn't match anything we have */
0x01, 6, "ar",
0x02, 1, "bg",
0x03, 2, "ca",
0x04, 11, "zh",
0x05, 0, "cs",
0x06, 2, "da",
0x07, 2, "de",
0x08, 3, "el",
0x09, 2, "en",
0x0a, 2, "es",
0x0b, 2, "fi",
0x0c, 2, "fr",
0x0d, 5, "iw",
0x0e, 0, "hu",
0x0f, 2, "is",
0x10, 2, "it",
0x11, 10, "ja",
0x12, 12, "ko",
0x13, 2, "nl",
0x14, 2, "no",
0x15, 0, "pl",
0x16, 2, "pt",
0x17, 2, "rm",
0x18, 0, "ro",
0x19, 1, "ru",
0x1a, 0, "sr",
0x1b, 0, "sk",
0x1c, 0, "sq",
0x1d, 2, "sv",
0x1e, 9, "th",
0x1f, 4, "tr",
0x20, 2, "ur",
0x21, 2, "in",
0x22, 1, "uk",
0x23, 1, "be",
0x24, 0, "sl",
0x25, 7, "et",
0x26, 7, "lv",
0x27, 7, "lt",
0x28, 1, "tg",
0x29, 6, "fa",
0x2a, 8, "vi",
0x2b, 14, "hy",
0x2c, 4, "az",
0x2d, 2, "eu",
/* 0x2e, 2, "??", no ISO-639 abbreviation for Sorbian */
0x2f, 1, "mk",
0x31, 2, "ts",
0x32, 2, "tn",
0x34, 2, "xh",
0x35, 2, "zu",
0x36, 2, "af",
0x37, 14, "ka",
0x38, 2, "fo",
0x39, 14, "hi",
0x3a, 14, "mt",
0x3b, 2, "se",
0x3c, 2, "gd",
0x3d, 2, "yi",
0x3e, 2, "ms",
0x3f, 1, "kk",
0x40, 1, "ky",
0x41, 2, "sw",
0x42, 0, "tk",
0x43, 1, "uz",
0x44, 1, "tt",
0x45, 14, "bn",
0x46, 14, "pa",
0x47, 14, "gu",
0x48, 14, "or",
0x49, 14, "ta",
0x4a, 14, "te",
0x4b, 14, "kn",
0x4c, 14, "ml",
0x4d, 14, "as",
0x4e, 14, "mr",
0x4f, 14, "sa",
0x50, 1, "mn",
0x51, 14, "bo",
0x52, 1, "cy",
0x53, 14, "km",
0x54, 14, "lo",
0x56, 2, "gl",
0x5b, 14, "si",
0x5d, 14, "iu",
0x5e, 14, "am",
/* 0x5f, 2, "??", no ISO-639 abbreviation for Tamazight */
0x68, 2, "ha",
0x6a, 2, "yo",
0x6b, 2, "qu",
0x6d, 1, "ba",
0x6f, 2, "kl",
0x70, 2, "ig",
/* 0x78, 14, "??", no ISO-639 abbreviation for Yi */
0x7e, 2, "br",
0x80, 6, "ug",
0x81, 14, "mi",
0x82, 2, "oc",
0x83, 2, "co",
/* 0x84, 2, "??", no ISO-639 abbreviation for Alsatian */
/* 0x85, 1, "??", no ISO-639 abbreviation for Yakut */
/* 0x86, 2, "??", no ISO-639 abbreviation for K'iche */
0x87, 2, "rw",
0x88, 2, "wo",
/* 0x8c, 6, "??", no ISO-639 abbreviation for Dari */
/* mappings for real Windows LCID values */
0x0401, 6, "ar_SA",
0x0402, 1, "bg_BG",
0x0403, 2, "ca_ES",
0x0404, 13, "zh_TW",
0x0405, 0, "cs_CZ",
0x0406, 2, "da_DK",
0x0407, 2, "de_DE",
0x0408, 3, "el_GR",
0x0409, 2, "en_US",
0x040a, 2, "es_ES", /* (traditional sort) */
0x040b, 2, "fi_FI",
0x040c, 2, "fr_FR",
0x040d, 5, "iw_IL",
0x040e, 0, "hu_HU",
0x040f, 2, "is_IS",
0x0410, 2, "it_IT",
0x0411, 10, "ja_JP",
0x0412, 12, "ko_KR",
0x0413, 2, "nl_NL",
0x0414, 2, "no_NO",
0x0415, 0, "pl_PL",
0x0416, 2, "pt_BR",
0x0417, 2, "rm_CH",
0x0418, 0, "ro_RO",
0x0419, 1, "ru_RU",
0x041a, 0, "hr_HR",
0x041b, 0, "sk_SK",
0x041c, 0, "sq_AL",
0x041d, 2, "sv_SE",
0x041e, 9, "th_TH",
0x041f, 4, "tr_TR",
0x0420, 6, "ur_PK",
0x0421, 2, "in_ID",
0x0422, 1, "uk_UA",
0x0423, 1, "be_BY",
0x0424, 0, "sl_SI",
0x0425, 7, "et_EE",
0x0426, 7, "lv_LV",
0x0427, 7, "lt_LT",
0x0428, 1, "tg_TJ",
0x0429, 6, "fa_IR",
0x042a, 8, "vi_VN",
0x042b, 14, "hy_AM", /* Armenian */
0x042c, 4, "az_AZ", /* Azeri_Latin */
0x042d, 2, "eu_ES",
/* 0x042e, 2, "??", no ISO-639 abbreviation for Upper Sorbian */
0x042f, 1, "mk_MK",
/* 0x0430, 2, "??", no ISO-639 abbreviation for Sutu */
0x0431, 2, "ts", /* (country?) */
0x0432, 2, "tn_ZA",
/* 0x0433, 2, "??", no ISO-639 abbreviation for Venda */
0x0434, 2, "xh_ZA",
0x0435, 2, "zu_ZA",
0x0436, 2, "af_ZA",
0x0437, 14, "ka_GE", /* Georgian */
0x0438, 2, "fo_FO",
0x0439, 14, "hi_IN",
0x043a, 14, "mt_MT",
0x043b, 2, "se_NO", /* Sami, Northern - Norway */
0x043c, 2, "gd_GB",
0x043d, 2, "yi", /* (country?) */
0x043e, 2, "ms_MY",
0x043f, 1, "kk_KZ", /* Kazakh */
0x0440, 1, "ky_KG", /* Kyrgyz */
0x0441, 2, "sw_KE",
0x0442, 0, "tk_TM",
0x0443, 4, "uz_UZ", /* Uzbek_Latin */
0x0444, 1, "tt_RU", /* Tatar */
0x0445, 14, "bn_IN", /* Bengali */
0x0446, 14, "pa_IN", /* Punjabi */
0x0447, 14, "gu_IN", /* Gujarati */
0x0448, 14, "or_IN", /* Oriya */
0x0449, 14, "ta_IN", /* Tamil */
0x044a, 14, "te_IN", /* Telugu */
0x044b, 14, "kn_IN", /* Kannada */
0x044c, 14, "ml_IN", /* Malayalam */
0x044d, 14, "as_IN", /* Assamese */
0x044e, 14, "mr_IN", /* Marathi */
0x044f, 14, "sa_IN", /* Sanskrit */
0x0450, 1, "mn_MN", /* Mongolian */
0x0451, 14, "bo_CN", /* Tibetan */
0x0452, 2, "cy_GB", /* Welsh */
0x0453, 14, "km_KH", /* Khmer */
0x0454, 14, "lo_LA", /* Lao */
0x0456, 2, "gl_ES", /* Galician */
/* 0x0457, 14, "??_IN", /* Konkani, no ISO-639 abbreviation*/
/* 0x045a, 14, "??_SY", /* Syriac, no ISO-639 abbreviation*/
0x045b, 14, "si_LK", /* Sinhala */
0x045d, 14, "iu_CA", /* Inuktitut */
0x045e, 14, "am_ET", /* Amharic */
0x0461, 14, "ne_NP", /* Nepali */
0x0462, 2, "fy_NL", /* Frisian */
0x0463, 6, "ps_AF", /* Pushto */
/* 0x0464, 2, "??_PH", /* Filipino, no ISO-639 abbreviation*/
0x0465, 14, "dv_MV", /* Divehi */
0x0468, 2, "ha_NG", /* Hausa */
0x046a, 2, "yo_NG", /* Yoruba */
0x046b, 2, "qu_BO", /* Quechua - Bolivia */
/* 0x046c, 2, "??_ZA", /* Northern Sotho, no ISO-639 abbreviation */
0x046d, 1, "ba_RU", /* Bashkir */
0x046e, 2, "lb_LU", /* Luxembourgish */
0x046f, 2, "kl_GL", /* Greenlandic */
0x0470, 2, "ig_NG", /* Igbo */
/* 0x0478, 14, "??_CN", /* Yi (PRC), no ISO-639 abbreviation */
/* 0x047a, 2, "??_CL", /* Mapudungun (Araucanian), no ISO-639 abbreviation */
/* 0x047c, 2, "??_CA", /* Mohawk, no ISO-639 abbreviation */
0x047e, 2, "br_FR", /* Breton */
0x0480, 6, "ug_CN", /* Uighur */
0x0481, 14, "mi_NZ", /* Maori - New Zealand */
0x0482, 2, "oc_FR", /* Occitan */
0x0483, 2, "co_FR", /* Corsican */
/* 0x0484, 2, "??_FR", /* Alsatian, no ISO-639 abbreviation */
/* 0x0485, 1, "??_RU", /* Yakut, no ISO-639 abbreviation */
/* 0x0486, 2, "??_GT", /* K'iche, no ISO-639 abbreviation */
0x0487, 2, "rw_RW", /* Kinyarwanda */
0x0488, 2, "wo_SN", /* Wolof */
/* 0x048c, 6, "??_AF", /* Dari, no ISO-639 abbreviation */
0x0801, 6, "ar_IQ",
0x0804, 11, "zh_CN",
0x0807, 2, "de_CH",
0x0809, 2, "en_GB",
0x080a, 2, "es_MX",
0x080c, 2, "fr_BE",
0x0810, 2, "it_CH",
0x0812, 15, "ko_KR", /* Korean(Johab)*/
0x0813, 2, "nl_BE",
0x0814, 2, "no_NO_NY",
0x0816, 2, "pt_PT",
0x0818, 0, "ro_MD",
0x0819, 1, "ru_MD",
0x081a, 0, "sr_CS",
0x081d, 2, "sv_FI",
0x082c, 1, "az_AZ", /* Azeri_Cyrillic */
/* 0x082e, 2, "??", no ISO-639 abbreviation for Lower Sorbian */
0x083b, 2, "se_SE", /* Sami, Northern - Sweden */
0x083c, 2, "ga_IE",
0x083e, 2, "ms_BN",
0x0843, 1, "uz_UZ", /* Uzbek_Cyrillic */
0x0845, 14, "bn_BD", /* Bengali */
0x0850, 14, "mn_CN", /* Traditional Mongolian */
0x085d, 2, "iu_CA", /* Inuktitut */
/* 0x085f, 2, "??_DZ", no ISO-639 abbreviation for Tamazight */
0x086b, 2, "qu_EC", /* Quechua - Ecuador */
0x0c01, 6, "ar_EG",
0x0c04, 13, "zh_HK",
0x0c07, 2, "de_AT",
0x0c09, 2, "en_AU",
0x0c0a, 2, "es_ES", /* (modern sort) */
0x0c0c, 2, "fr_CA",
0x0c1a, 1, "sr_CS",
0x0c3b, 2, "se_FI", /* Sami, Northern - Finland */
0x0c6b, 2, "qu_PE", /* Quechua - Peru */
0x1001, 6, "ar_LY",
0x1004, 11, "zh_SG",
0x1007, 2, "de_LU",
0x1009, 2, "en_CA",
0x100a, 2, "es_GT",
0x100c, 2, "fr_CH",
0x101a, 0, "hr_BA",
/* 0x103b, 2, "??_NO", /* Sami, Lule - Norway */
0x1401, 6, "ar_DZ",
0x1404, 13, "zh_MO",
0x1407, 2, "de_LI",
0x1409, 2, "en_NZ",
0x140a, 2, "es_CR",
0x140c, 2, "fr_LU",
0x141a, 0, "bs_BA",
/* 0x143b, 2, "??_SE", /* Sami, Lule - Sweden */
0x1801, 6, "ar_MA",
0x1809, 2, "en_IE",
0x180a, 2, "es_PA",
0x180c, 2, "fr_MC",
0x181a, 0, "sr_BA",
/* 0x183b, 2, "??_NO", /* Sami, Southern - Norway */
0x1c01, 6, "ar_TN",
0x1c09, 2, "en_ZA",
0x1c0a, 2, "es_DO",
0x1c1a, 1, "sr_BA",
/* 0x1c3b, 2, "??_SE", /* Sami, Southern - Sweden */
0x2001, 6, "ar_OM",
0x2009, 2, "en_JM",
0x200a, 2, "es_VE",
0x201a, 0, "bs_BA", /* Bosnian (Cyrillic) */
/* 0x203b, 2, "??_FI", /* Sami, Skolt - Finland */
0x2401, 6, "ar_YE",
0x2409, 2, "en", /* ("Caribbean", which could be any of many countries) */
0x240a, 2, "es_CO",
/* 0x243b, 2, "??_FI", /* Sami, Inari - Finland */
0x2801, 6, "ar_SY",
0x2809, 2, "en_BZ",
0x280a, 2, "es_PE",
0x2c01, 6, "ar_JO",
0x2c09, 2, "en_TT",
0x2c0a, 2, "es_AR",
0x3001, 6, "ar_LB",
0x3009, 2, "en_ZW",
0x300a, 2, "es_EC",
0x3401, 6, "ar_KW",
0x3409, 2, "en_PH",
0x340a, 2, "es_CL",
0x3801, 6, "ar_AE",
0x380a, 2, "es_UY",
0x3c01, 6, "ar_BH",
0x3c0a, 2, "es_PY",
0x4001, 6, "ar_QA",
0x4009, 2, "en_IN",
0x400a, 2, "es_BO",
0x4409, 2, "en_MY",
0x440a, 2, "es_SV",
0x4809, 2, "en_SG",
0x480a, 2, "es_HN",
0x4c0a, 2, "es_NI",
0x500a, 2, "es_PR",
0x540a, 2, "es_US"
};
/*
* binary-search our list of LANGID values. If we don't find the
* one we're looking for, mask out the country code and try again
* with just the primary language ID
*/
static int
getLocaleEntryIndex(LANGID langID)
{
int index = -1;
int tries = 0;
do {
int lo, hi, mid;
lo = 0;
hi = sizeof(langIDMap) / sizeof(LANGIDtoLocale);
while (index == -1 && lo < hi) {
mid = (lo + hi) / 2;
if (langIDMap[mid].langID == langID) {
index = mid;
} else if (langIDMap[mid].langID > langID) {
hi = mid;
} else {
lo = mid + 1;
}
}
langID = PRIMARYLANGID(langID);
++tries;
} while (index == -1 && tries < 2);
return index;
}
static char *
getEncodingInternal(int index)
getEncodingInternal(LCID lcid)
{
char * ret = encoding_names[langIDMap[index].encoding];
char * ret = malloc(16);
int codepage;
if (GetLocaleInfo(lcid,
LOCALE_IDEFAULTANSICODEPAGE,
ret+2, 14) == 0) {
codepage = 1252;
} else {
codepage = atoi(ret+2);
}
switch (codepage) {
case 0:
strcpy(ret, "UTF-8");
break;
case 874: /* 9:Thai */
case 932: /* 10:Japanese */
case 949: /* 12:Korean Extended Wansung */
case 950: /* 13:Chinese (Taiwan, Hongkong, Macau) */
case 1361: /* 15:Korean Johab */
ret[0] = 'M';
ret[1] = 'S';
break;
case 936:
strcpy(ret, "GBK");
break;
case 54936:
strcpy(ret, "GB18030");
break;
default:
ret[0] = 'C';
ret[1] = 'p';
break;
}
//Traditional Chinese Windows should use MS950_HKSCS_XP as the
//default encoding, if HKSCS patch has been installed.
@ -460,7 +95,7 @@ getEncodingInternal(int index)
WCHAR unicodeChar;
MultiByteToWideChar(CP_ACP, 0, mbChar, 2, &unicodeChar, 1);
if (unicodeChar == 0x92db) {
ret = "MS950_HKSCS_XP";
strcpy(ret, "MS950_HKSCS_XP");
}
} else {
//SimpChinese Windows should use GB18030 as the default
@ -476,7 +111,7 @@ getEncodingInternal(int index)
strcat(systemPath, "\\FONTS\\SimSun18030.ttc");
if ((f = fopen(systemPath, "r")) != NULL) {
fclose(f);
ret = "GB18030";
strcpy(ret, "GB18030");
}
}
}
@ -489,25 +124,35 @@ getEncodingInternal(int index)
DllExport const char *
getEncodingFromLangID(LANGID langID)
{
int index = getLocaleEntryIndex(langID);
if (index != (-1)) {
return getEncodingInternal(index);
} else {
return "Cp1252";
}
return getEncodingInternal(MAKELCID(langID, SORT_DEFAULT));
}
DllExport const char *
getJavaIDFromLangID(LANGID langID)
{
int index = getLocaleEntryIndex(langID);
char * lang;
char * ctry;
char * vrnt;
char * enc;
char * ret = malloc(16);
if (index != (-1)) {
return langIDMap[index].javaID;
SetupI18nProps(MAKELCID(langID, SORT_DEFAULT), &lang, &ctry, &vrnt, &enc);
if (ctry[0] != '\0') {
if (vrnt[0] != '\0') {
sprintf(ret, "%s_%s_%s", lang, ctry, vrnt);
} else {
sprintf(ret, "%s_%s", lang, ctry);
}
} else {
return NULL;
strcpy(ret, lang);
}
free(lang);
free(ctry);
free(vrnt);
free(enc);
return ret;
}
/*
@ -644,6 +289,58 @@ cpu_isalist(void)
return NULL;
}
#define PROPSIZE 3 // two-letter + null terminator
static void
SetupI18nProps(LCID lcid, char** language, char** country,
char** variant, char** encoding) {
/* country */
*country = malloc(PROPSIZE);
if (GetLocaleInfo(lcid,
LOCALE_SISO3166CTRYNAME, *country, PROPSIZE) == 0) {
(*country)[0] = '\0';
}
/* language */
*language = malloc(PROPSIZE);
if (lcid == 0x46c) {
/* Windows returns non-existent language code "ns" for Northern Sotho.
* Defaults to en_US
*/
strcpy(*language, "en");
strcpy(*country, "US");
} else if (GetLocaleInfo(lcid,
LOCALE_SISO639LANGNAME, *language, PROPSIZE) == 0) {
if (lcid == 0x465) {
/* for some reason, Windows returns "div" for this Divehi LCID, even though
* there is a two letter language code "dv". Tweak it here.
*/
strcpy(*language, "dv");
strcpy(*country, "MV");
} else {
/* defaults to en_US */
strcpy(*language, "en");
strcpy(*country, "US");
}
}
/* variant */
*variant = malloc(PROPSIZE);
(*variant)[0] = '\0';
/* handling for Norwegian */
if (strcmp(*language, "nb") == 0) {
strcpy(*language, "no");
strcpy(*country , "NO");
} else if (strcmp(*language, "nn") == 0) {
strcpy(*language, "no");
strcpy(*country , "NO");
strcpy(*variant, "NY");
}
/* encoding */
*encoding = getEncodingInternal(lcid);
}
java_props_t *
GetJavaProperties(JNIEnv* env)
{
@ -876,62 +573,31 @@ GetJavaProperties(JNIEnv* env)
* query the system for the current system default locale
* (which is a Windows LCID value),
*/
LANGID langID = LANGIDFROMLCID(GetUserDefaultLCID());
LANGID sysLangID = LANGIDFROMLCID(GetSystemDefaultLCID());
LCID userDefaultLCID = GetUserDefaultLCID();
LCID systemDefaultLCID = GetSystemDefaultLCID();
LCID userDefaultUILang = GetUserDefaultUILanguage();
{
int index = getLocaleEntryIndex(langID);
char * display_encoding;
/*
* if we didn't find the LCID that the system returned to us,
* we don't have a Java locale ID that corresponds to it.
* Fall back on en_US.
*/
if (index == -1) {
sprops.language = "en";
sprops.country = "US";
sprops.encoding = "Cp1252";
} else {
SetupI18nProps(userDefaultUILang,
&sprops.language,
&sprops.country,
&sprops.variant,
&display_encoding);
SetupI18nProps(userDefaultLCID,
&sprops.format_language,
&sprops.format_country,
&sprops.format_variant,
&sprops.encoding);
SetupI18nProps(userDefaultUILang,
&sprops.display_language,
&sprops.display_country,
&sprops.display_variant,
&display_encoding);
/* otherwise, look up the corresponding Java locale ID from
* the list of Java locale IDs and set up the system properties
* accordingly.
*/
char* lang;
char* ctry;
char* variant;
lang = strdup(langIDMap[index].javaID);
ctry = lang;
while (*ctry != '_' && *ctry != 0)
++ctry;
if (*ctry == '_') {
*ctry++ = 0;
}
variant = ctry;
while (*variant != '_' && *variant != 0)
++variant;
if (*variant == '_') {
*variant++ = 0;
}
sprops.language = lang;
sprops.country = ctry;
sprops.variant = variant;
sprops.encoding = getEncodingInternal(index);
}
index = getLocaleEntryIndex(sysLangID);
if (index == -1) {
sprops.sun_jnu_encoding = "Cp1252";
} else {
sprops.sun_jnu_encoding = getEncodingInternal(index);
}
if (langID == 0x0c04 && ver.dwMajorVersion == 6) {
sprops.sun_jnu_encoding = getEncodingInternal(systemDefaultLCID);
if (LANGIDFROMLCID(userDefaultLCID) == 0x0c04 && ver.dwMajorVersion == 6) {
// MS claims "Vista has built-in support for HKSCS-2004.
// All of the HKSCS-2004 characters have Unicode 4.1.
// PUA code point assignments". But what it really means

View File

@ -201,6 +201,7 @@ AwtDataTransferer::LCIDToTextEncoding(JNIEnv *env, LCID lcid) {
throw std::bad_alloc();
}
env->SetByteArrayRegion(retval, 0, length, (jbyte *)encoding);
free((void *)encoding);
return retval;
}

View File

@ -296,7 +296,9 @@ JNIEXPORT jobject JNICALL Java_sun_awt_windows_WInputMethod_getNativeLocale
// so we can reset this flag.
g_bUserHasChangedInputLang = FALSE;
return CreateLocaleObject(env, javaLocaleName);
jobject ret = CreateLocaleObject(env, javaLocaleName);
free((void *)javaLocaleName);
return ret;
} else {
return NULL;
}
@ -323,6 +325,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
const char * requested = env->GetStringUTFChars(localeString, &isCopy);
if ((current != NULL) && (strcmp(current, requested) == 0)) {
env->ReleaseStringUTFChars(localeString, requested);
free((void *)current);
return JNI_TRUE;
}
@ -352,6 +355,7 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WInputMethod_setNativeLocale
env->ReleaseStringUTFChars(localeString, requested);
free(hKLList);
free((void *)current);
return retValue;
CATCH_BAD_ALLOC_RET(JNI_FALSE);
@ -480,6 +484,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_awt_windows_WInputMethodDescriptor_getNa
env->SetObjectArrayElement(locales,
current,
CreateLocaleObject(env, javaLocaleNames[current]));
free((void *)javaLocaleNames[current]);
}
DASSERT(!safe_ExceptionOccurred(env));

View File

@ -58,7 +58,7 @@ public class Constructors {
}
static void locale(Formatter f) {
locale(f, Locale.getDefault());
locale(f, Locale.getDefault(Locale.Category.FORMAT));
}
static void locale(Formatter f, Locale l) {

View File

@ -0,0 +1,79 @@
#!/bin/sh
#
# @test
# @bug 4700857
# @summary tests for Locale.getDefault(Locale.Category) and
# Locale.setDefault(Locale.Category, Locale)
# @build LocaleCategory
# @run shell/timeout=600 LocaleCategory.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTSRC=${TESTSRC}"
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTJAVA=${TESTJAVA}"
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTCLASSES=${TESTCLASSES}"
echo "CLASSPATH=${CLASSPATH}"
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
SunOS | Linux )
PS=":"
FS="/"
;;
Windows* )
PS=";"
FS="\\"
;;
* )
echo "Unrecognized system!"
exit 1;
;;
esac
# test user.xxx.display user.xxx.format properties
# run
RUNCMD="${TESTJAVA}${FS}bin${FS}java -classpath ${TESTCLASSES} -Duser.language.display=ja -Duser.language.format=zh LocaleCategory"
echo ${RUNCMD}
${RUNCMD}
result=$?
if [ $result -eq 0 ]
then
echo "Execution successful"
else
echo "Execution of the test case failed."
fi
# test user.xxx properties overriding user.xxx.display/format
# run
RUNCMD="${TESTJAVA}${FS}bin${FS}java -classpath ${TESTCLASSES} -Duser.language=en -Duser.language.display=ja -Duser.language.format=zh LocaleCategory"
echo ${RUNCMD}
${RUNCMD}
result=$?
if [ $result -eq 0 ]
then
echo "Execution successful"
else
echo "Execution of the test case failed."
fi
exit $result

View File

@ -231,8 +231,15 @@ import java.util.Locale;
public class PrintDefaultLocale {
public static void main(String[] args) {
System.out.println(Locale.getDefault().toString());
System.out.println(Locale.getDefault().getDisplayName(Locale.US));
System.out.println(Charset.defaultCharset());
System.out.printf("default locale: ID: %s, Name: %s\n",
Locale.getDefault().toString(),
Locale.getDefault().getDisplayName(Locale.US));
System.out.printf("display locale: ID: %s, Name: %s\n",
Locale.getDefault(Locale.Category.DISPLAY).toString(),
Locale.getDefault(Locale.Category.DISPLAY).getDisplayName(Locale.US));
System.out.printf("format locale: ID: %s, Name: %s\n",
Locale.getDefault(Locale.Category.FORMAT).toString(),
Locale.getDefault(Locale.Category.FORMAT).getDisplayName(Locale.US));
System.out.printf("default charset: %s\n", Charset.defaultCharset());
}
}

View File

@ -29,100 +29,233 @@
* WARNING: This tool directly modifies the locale info in the Windows registry.
* It may not work with the Windows versions after Windows XP SP2. Also,
* if the test did not complete or was manually killed, you will need to reset
* the user default locale in the Control Panel manually.
* the user default locale in the Control Panel manually. This executable has
* to be run with the "Administrator" privilege.
*
* Usage: "deflocale.exe <java launcher> PrintDefaultLocale
*
* How to compile: "cl deflocale.c advapi32.lib"
* How to compile: "cl -DUNICODE -D_UNICODE deflocale.c user32.lib advapi32.lib"
*/
#include <windows.h>
#include <stdio.h>
#include <memory.h>
char* launcher;
char szBuffer[MAX_PATH];
wchar_t* launcher;
wchar_t szBuffer[MAX_PATH];
LCID LCIDArray[1024];
int numLCIDs = 0;
BOOL isWin7orUp = FALSE;
void testLCID(int anLCID) {
// for Windows 7
BOOL (WINAPI * pfnEnumSystemLocalesEx)(LPVOID, DWORD, LPARAM, LPVOID);
BOOL (WINAPI * pfnEnumUILanguages)(LPVOID, DWORD, LPARAM);
LCID (WINAPI * pfnLocaleNameToLCID)(LPCWSTR, DWORD);
int (WINAPI * pfnLCIDToLocaleName)(LCID, LPWSTR, int, DWORD);
wchar_t* LocaleNamesArray[1024];
wchar_t* UILangNamesArray[1024];
int numLocaleNames = 0;
int numUILangNames = 0;
void launchAndWait() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(NULL, launcher, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)==0) {
wprintf(L"CreateProcess failed with the error code: %x\n", GetLastError());
}
WaitForSingleObject( pi.hProcess, INFINITE );
}
void testLocale(int anLCID, wchar_t* pName) {
HKEY hk;
printf("\n");
printf("OS Locale (lcid: %x): ", anLCID);
if (pName != NULL && wcslen(pName) == 2) {
// ignore language only locale.
return;
}
wprintf(L"\n");
wprintf(L"OS Locale (lcid: %x", anLCID);
if (pName != NULL) {
wprintf(L", name: %s", pName);
}
GetLocaleInfo(anLCID, LOCALE_SENGLANGUAGE, szBuffer, MAX_PATH);
printf("%s (", szBuffer);
wprintf(L"): %s (", szBuffer);
GetLocaleInfo(anLCID, LOCALE_SENGCOUNTRY, szBuffer, MAX_PATH);
printf("%s) - ", szBuffer);
wprintf(L"%s) - ", szBuffer);
GetLocaleInfo(anLCID, LOCALE_IDEFAULTANSICODEPAGE, szBuffer, MAX_PATH);
printf("%s\n", szBuffer);
wprintf(L"%s\n", szBuffer);
fflush(0);
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\International", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
BYTE original[16];
BYTE test[16];
DWORD cb = 16;
STARTUPINFO si;
PROCESS_INFORMATION pi;
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\International", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
wchar_t originalLocale[16];
wchar_t testLocale[16];
wchar_t* pKeyName;
DWORD cb = sizeof(originalLocale);
DWORD cbTest;
RegQueryValueEx(hk, "Locale", 0, 0, original, &cb);
sprintf(test, "%08x", anLCID);
RegSetValueEx(hk, "Locale", 0, REG_SZ, test, cb);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(NULL, launcher, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)==0) {
printf("CreateProcess failed with the error code: %x\n", GetLastError());
if (isWin7orUp) {
pKeyName = L"LocaleName";
wcscpy(testLocale, pName);
cbTest = wcslen(pName) * sizeof(wchar_t);
} else {
pKeyName = L"Locale";
swprintf(testLocale, L"%08x", anLCID);
cbTest = sizeof(wchar_t) * 8;
}
WaitForSingleObject( pi.hProcess, INFINITE );
RegSetValueEx(hk, "Locale", 0, REG_SZ, original, cb);
RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalLocale, &cb);
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testLocale, cbTest );
launchAndWait();
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalLocale, cb);
RegCloseKey(hk);
}
}
BOOL CALLBACK EnumLocaleProc(LPTSTR lpLocaleStr) {
sscanf(lpLocaleStr, "%08x", &LCIDArray[numLCIDs]);
void testUILang(wchar_t* pName) {
HKEY hk;
wprintf(L"\n");
wprintf(L"OS UI Language (name: %s)\n", pName);
fflush(0);
if (RegOpenKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &hk) == ERROR_SUCCESS) {
wchar_t originalUILang[16];
wchar_t testUILang[16];
wchar_t* pKeyName;
DWORD cb = sizeof(originalUILang);
DWORD cbTest = wcslen(pName) * sizeof(wchar_t);
pKeyName = L"PreferredUILanguages";
wcscpy(testUILang, pName);
cbTest = wcslen(pName) * sizeof(wchar_t);
RegQueryValueEx(hk, pKeyName, 0, 0, (LPBYTE)originalUILang, &cb);
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)testUILang, cbTest);
launchAndWait();
RegSetValueEx(hk, pKeyName, 0, REG_SZ, (LPBYTE)originalUILang, cb);
RegCloseKey(hk);
}
}
BOOL CALLBACK EnumLocalesProc(LPWSTR lpLocaleStr) {
swscanf(lpLocaleStr, L"%08x", &LCIDArray[numLCIDs]);
numLCIDs ++;
return TRUE;
}
BOOL CALLBACK EnumLocalesProcEx(LPWSTR lpLocaleStr, DWORD flags, LPARAM lp) {
wchar_t* pName = malloc((wcslen(lpLocaleStr) + 1) * sizeof(wchar_t *));
wcscpy(pName, lpLocaleStr);
LocaleNamesArray[numLocaleNames] = pName;
numLocaleNames ++;
return TRUE;
}
BOOL CALLBACK EnumUILanguagesProc(LPWSTR lpUILangStr, LPARAM lp) {
wchar_t* pName = malloc((wcslen(lpUILangStr) + 1) * sizeof(wchar_t *));
wcscpy(pName, lpUILangStr);
UILangNamesArray[numUILangNames] = pName;
numUILangNames ++;
return TRUE;
}
int sortLCIDs(LCID * pLCID1, LCID * pLCID2) {
if (*pLCID1 < *pLCID2) return (-1);
if (*pLCID1 == *pLCID2) return 0;
if (*pLCID1 > *pLCID2) return 1;
return 1;
}
int sortLocaleNames(wchar_t** ppName1, wchar_t** ppName2) {
LCID l1 = pfnLocaleNameToLCID(*ppName1, 0);
LCID l2 = pfnLocaleNameToLCID(*ppName2, 0);
return sortLCIDs(&l1, &l2);
}
int main(int argc, char** argv) {
OSVERSIONINFO osvi;
LPTSTR commandline = GetCommandLine();
LPWSTR commandline = GetCommandLine();
int i;
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx(&osvi);
printf("# OSVersionInfo\n");
printf("# MajorVersion: %d\n", osvi.dwMajorVersion);
printf("# MinorVersion: %d\n", osvi.dwMinorVersion);
printf("# BuildNumber: %d\n", osvi.dwBuildNumber);
printf("# CSDVersion: %s\n", osvi.szCSDVersion);
printf("\n");
wprintf(L"# OSVersionInfo\n");
wprintf(L"# MajorVersion: %d\n", osvi.dwMajorVersion);
wprintf(L"# MinorVersion: %d\n", osvi.dwMinorVersion);
wprintf(L"# BuildNumber: %d\n", osvi.dwBuildNumber);
wprintf(L"# CSDVersion: %s\n", osvi.szCSDVersion);
wprintf(L"\n");
fflush(0);
launcher = strchr(commandline, ' ')+1;
while (*launcher == ' ') {
launcher = wcschr(commandline, L' ')+1;
while (*launcher == L' ') {
launcher++;
}
// Enumerate locales
EnumSystemLocales(EnumLocaleProc, LCID_INSTALLED);
isWin7orUp = (osvi.dwMajorVersion > 6) ||
(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 1);
// Sort LCIDs
qsort(LCIDArray, numLCIDs, sizeof(LCID), (void *)sortLCIDs);
if (!isWin7orUp) {
// Enumerate locales
EnumSystemLocales(EnumLocalesProc, LCID_INSTALLED);
// Sort LCIDs
qsort(LCIDArray, numLCIDs, sizeof(LCID), (void *)sortLCIDs);
} else {
// For Windows 7, use "LocaleName" registry key for the user locale
// as they seem to switch from "Locale".
HMODULE hmod = GetModuleHandle(L"kernel32");
*(FARPROC*)&pfnEnumSystemLocalesEx =
GetProcAddress(hmod, "EnumSystemLocalesEx");
*(FARPROC*)&pfnEnumUILanguages =
GetProcAddress(hmod, "EnumUILanguagesW");
*(FARPROC*)&pfnLocaleNameToLCID =
GetProcAddress(hmod, "LocaleNameToLCID");
*(FARPROC*)&pfnLCIDToLocaleName =
GetProcAddress(hmod, "LCIDToLocaleName");
if (pfnEnumSystemLocalesEx != NULL &&
pfnEnumUILanguages != NULL &&
pfnLocaleNameToLCID != NULL &&
pfnLCIDToLocaleName != NULL) {
// Enumerate locales
pfnEnumSystemLocalesEx(EnumLocalesProcEx,
1, // LOCALE_WINDOWS
(LPARAM)NULL, NULL);
// Enumerate UI Languages.
pfnEnumUILanguages(EnumUILanguagesProc,
0x8, // MUI_LANGUAGE_NAME
(LPARAM)NULL);
} else {
wprintf(L"Could not get needed entry points. quitting.\n");
exit(-1);
}
// Sort LocaleNames
qsort(LocaleNamesArray, numLocaleNames,
sizeof(wchar_t*), (void *)sortLocaleNames);
qsort(UILangNamesArray, numUILangNames,
sizeof(wchar_t*), (void *)sortLocaleNames);
}
// Execute enumeration of Java default locales
for (i = 0; i < numLCIDs; i ++) {
testLCID(LCIDArray[i]);
if (isWin7orUp) {
for (i = 0; i < numLocaleNames; i ++) {
testLocale(pfnLocaleNameToLCID(LocaleNamesArray[i], 0),
LocaleNamesArray[i]);
}
for (i = 0; i < numUILangNames; i ++) {
testUILang(UILangNamesArray[i]);
}
} else {
for (i = 0; i < numLCIDs; i ++) {
testLocale(LCIDArray[i], NULL);
}
}
}

View File

@ -0,0 +1,7 @@
# data file for deflocale.sh. Each line must have two locales in the following order.
#
# LC_CTYPE LC_MESSAGES
ja_JP.UTF-8 zh_CN.UTF-8
zh_CN.UTF-8 en_US.UTF-8
C zh_CN.UTF-8

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,8 +31,21 @@
#
cat /etc/*release
uname -a
env LC_COLLATE=C ls /usr/lib/locale | while read line; do
echo "Testing all available locales"
/usr/bin/locale -a | while read line; do
echo ""
echo "OS Locale: " $line
env LANG=$line LC_ALL=$line $1 PrintDefaultLocale
env LC_ALL= LC_CTYPE= LC_MESSAGES= LANG=$line $1 $2 $3 $4 $5 $6 $7 $8 $9 PrintDefaultLocale
done
echo ""
echo "Testing some typical combinations"
echo ""
while read lcctype lcmessages; do
if [ "$lcctype" = "#" -o "$lcctype" = "" ]; then
continue
fi
echo ""
echo "OS Locale (LC_CTYPE: "$lcctype", LC_MESSAGES: "$lcmessages")"
env LC_ALL= LC_CTYPE=$lcctype LC_MESSAGES=$lcmessages $1 $2 $3 $4 $5 $6 $7 $8 $9 PrintDefaultLocale
done < deflocale.input

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,861 +0,0 @@
# OSVersionInfo
# MajorVersion: 5
# MinorVersion: 1
# BuildNumber: 2600
# CSDVersion: Service Pack 2
OS Locale (lcid: 401): Arabic (Saudi Arabia) - 1256
ar_SA
Arabic (Saudi Arabia)
windows-1256
OS Locale (lcid: 402): Bulgarian (Bulgaria) - 1251
bg_BG
Bulgarian (Bulgaria)
windows-1251
OS Locale (lcid: 403): Catalan (Spain) - 1252
ca_ES
Catalan (Spain)
windows-1252
OS Locale (lcid: 404): Chinese (Taiwan) - 950
zh_TW
Chinese (Taiwan)
x-windows-950
OS Locale (lcid: 405): Czech (Czech Republic) - 1250
cs_CZ
Czech (Czech Republic)
windows-1250
OS Locale (lcid: 406): Danish (Denmark) - 1252
da_DK
Danish (Denmark)
windows-1252
OS Locale (lcid: 407): German (Germany) - 1252
de_DE
German (Germany)
windows-1252
OS Locale (lcid: 408): Greek (Greece) - 1253
el_GR
Greek (Greece)
windows-1253
OS Locale (lcid: 409): English (United States) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 40a): Spanish (Spain) - 1252
es_ES
Spanish (Spain)
windows-1252
OS Locale (lcid: 40b): Finnish (Finland) - 1252
fi_FI
Finnish (Finland)
windows-1252
OS Locale (lcid: 40c): French (France) - 1252
fr_FR
French (France)
windows-1252
OS Locale (lcid: 40d): Hebrew (Israel) - 1255
iw_IL
Hebrew (Israel)
windows-1255
OS Locale (lcid: 40e): Hungarian (Hungary) - 1250
hu_HU
Hungarian (Hungary)
windows-1250
OS Locale (lcid: 40f): Icelandic (Iceland) - 1252
is_IS
Icelandic (Iceland)
windows-1252
OS Locale (lcid: 410): Italian (Italy) - 1252
it_IT
Italian (Italy)
windows-1252
OS Locale (lcid: 411): Japanese (Japan) - 932
ja_JP
Japanese (Japan)
windows-31j
OS Locale (lcid: 412): Korean (Korea) - 949
ko_KR
Korean (South Korea)
x-windows-949
OS Locale (lcid: 413): Dutch (Netherlands) - 1252
nl_NL
Dutch (Netherlands)
windows-1252
OS Locale (lcid: 414): Norwegian (Bokmål) (Norway) - 1252
no_NO
Norwegian (Norway)
windows-1252
OS Locale (lcid: 415): Polish (Poland) - 1250
pl_PL
Polish (Poland)
windows-1250
OS Locale (lcid: 416): Portuguese (Brazil) - 1252
pt_BR
Portuguese (Brazil)
windows-1252
OS Locale (lcid: 417): Romansh (Switzerland) - 1252
rm_CH
Raeto-Romance (Switzerland)
windows-1252
OS Locale (lcid: 418): Romanian (Romania) - 1250
ro_RO
Romanian (Romania)
windows-1250
OS Locale (lcid: 419): Russian (Russia) - 1251
ru_RU
Russian (Russia)
windows-1251
OS Locale (lcid: 41a): Croatian (Croatia) - 1250
hr_HR
Croatian (Croatia)
windows-1250
OS Locale (lcid: 41b): Slovak (Slovakia) - 1250
sk_SK
Slovak (Slovakia)
windows-1250
OS Locale (lcid: 41c): Albanian (Albania) - 1250
sq_AL
Albanian (Albania)
windows-1250
OS Locale (lcid: 41d): Swedish (Sweden) - 1252
sv_SE
Swedish (Sweden)
windows-1252
OS Locale (lcid: 41e): Thai (Thailand) - 874
th_TH
Thai (Thailand)
x-windows-874
OS Locale (lcid: 41f): Turkish (Turkey) - 1254
tr_TR
Turkish (Turkey)
windows-1254
OS Locale (lcid: 420): Urdu (Islamic Republic of Pakistan) - 1256
ur_PK
Urdu (Pakistan)
windows-1256
OS Locale (lcid: 421): Indonesian (Indonesia) - 1252
in_ID
Indonesian (Indonesia)
windows-1252
OS Locale (lcid: 422): Ukrainian (Ukraine) - 1251
uk_UA
Ukrainian (Ukraine)
windows-1251
OS Locale (lcid: 423): Belarusian (Belarus) - 1251
be_BY
Belarusian (Belarus)
windows-1251
OS Locale (lcid: 424): Slovenian (Slovenia) - 1250
sl_SI
Slovenian (Slovenia)
windows-1250
OS Locale (lcid: 425): Estonian (Estonia) - 1257
et_EE
Estonian (Estonia)
windows-1257
OS Locale (lcid: 426): Latvian (Latvia) - 1257
lv_LV
Latvian (Latvia)
windows-1257
OS Locale (lcid: 427): Lithuanian (Lithuania) - 1257
lt_LT
Lithuanian (Lithuania)
windows-1257
OS Locale (lcid: 429): Farsi (Iran) - 1256
fa_IR
Persian (Iran)
windows-1256
OS Locale (lcid: 42a): Vietnamese (Viet Nam) - 1258
vi_VN
Vietnamese (Vietnam)
windows-1258
OS Locale (lcid: 42b): Armenian (Armenia) - 0
hy_AM
Armenian (Armenia)
UTF-8
OS Locale (lcid: 42c): Azeri (Latin) (Azerbaijan) - 1254
az_AZ
Azerbaijani (Azerbaijan)
windows-1254
OS Locale (lcid: 42d): Basque (Spain) - 1252
eu_ES
Basque (Spain)
windows-1252
OS Locale (lcid: 42f): FYRO Macedonian (Former Yugoslav Republic of Macedonia) - 1251
mk_MK
Macedonian (Macedonia)
windows-1251
OS Locale (lcid: 432): Tswana (South Africa) - 1252
tn_ZA
Tswana (South Africa)
windows-1252
OS Locale (lcid: 434): Xhosa (South Africa) - 1252
xh_ZA
Xhosa (South Africa)
windows-1252
OS Locale (lcid: 435): Zulu (South Africa) - 1252
zu_ZA
Zulu (South Africa)
windows-1252
OS Locale (lcid: 436): Afrikaans (South Africa) - 1252
af_ZA
Afrikaans (South Africa)
windows-1252
OS Locale (lcid: 437): Georgian (Georgia) - 0
ka_GE
Georgian (Georgia)
UTF-8
OS Locale (lcid: 438): Faroese (Faroe Islands) - 1252
fo_FO
Faroese (Faroe Islands)
windows-1252
OS Locale (lcid: 439): Hindi (India) - 0
hi_IN
Hindi (India)
UTF-8
OS Locale (lcid: 43a): Maltese (Malta) - 0
mt_MT
Maltese (Malta)
UTF-8
OS Locale (lcid: 43b): Sami (Northern) (Norway) - 1252
se_NO
Northern Sami (Norway)
windows-1252
OS Locale (lcid: 43e): Malay (Malaysia) - 1252
ms_MY
Malay (Malaysia)
windows-1252
OS Locale (lcid: 43f): Kazakh (Kazakhstan) - 1251
kk_KZ
Kazakh (Kazakhstan)
windows-1251
OS Locale (lcid: 440): Kyrgyz (Kyrgyzstan) - 1251
ky_KG
Kirghiz (Kyrgyzstan)
windows-1251
OS Locale (lcid: 441): Swahili (Kenya) - 1252
sw_KE
Swahili (Kenya)
windows-1252
OS Locale (lcid: 443): Uzbek (Latin) (Uzbekistan) - 1254
uz_UZ
Uzbek (Uzbekistan)
windows-1254
OS Locale (lcid: 444): Tatar (Russia) - 1251
tt_RU
Tatar (Russia)
windows-1251
OS Locale (lcid: 445): Bengali (India) - 0
bn_IN
Bengali (India)
UTF-8
OS Locale (lcid: 446): Punjabi (India) - 0
pa_IN
Panjabi (India)
UTF-8
OS Locale (lcid: 447): Gujarati (India) - 0
gu_IN
Gujarati (India)
UTF-8
OS Locale (lcid: 449): Tamil (India) - 0
ta_IN
Tamil (India)
UTF-8
OS Locale (lcid: 44a): Telugu (India) - 0
te_IN
Telugu (India)
UTF-8
OS Locale (lcid: 44b): Kannada (India) - 0
kn_IN
Kannada (India)
UTF-8
OS Locale (lcid: 44c): Malayalam (India) - 0
ml_IN
Malayalam (India)
UTF-8
OS Locale (lcid: 44e): Marathi (India) - 0
mr_IN
Marathi (India)
UTF-8
OS Locale (lcid: 44f): Sanskrit (India) - 0
sa_IN
Sanskrit (India)
UTF-8
OS Locale (lcid: 450): Mongolian (Mongolia) - 1251
mn_MN
Mongolian (Mongolia)
windows-1251
OS Locale (lcid: 452): Welsh (United Kingdom) - 1252
cy_GB
Welsh (United Kingdom)
windows-1252
OS Locale (lcid: 456): Galician (Spain) - 1252
gl_ES
Gallegan (Spain)
windows-1252
OS Locale (lcid: 457): Konkani (India) - 0
en_US
English (United States)
windows-1252
OS Locale (lcid: 45a): Syriac (Syria) - 0
en_US
English (United States)
windows-1252
OS Locale (lcid: 461): Nepali (Nepal) - 0
ne_NP
Nepali (Nepal)
UTF-8
OS Locale (lcid: 462): Frisian (Netherlands) - 1252
fy_NL
Frisian (Netherlands)
windows-1252
OS Locale (lcid: 463): Pashto (Afghanistan) - 1256
ps_AF
Pushto (Afghanistan)
windows-1256
OS Locale (lcid: 464): Filipino (Philippines) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 465): Divehi (Maldives) - 0
dv_MV
Divehi (Maldives)
UTF-8
OS Locale (lcid: 46b): Quechua (Bolivia) - 1252
qu_BO
Quechua (Bolivia)
windows-1252
OS Locale (lcid: 46c): Northern Sotho (South Africa) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 46e): Luxembourgish (Luxembourg) - 1252
lb_LU
Luxembourgish (Luxembourg)
windows-1252
OS Locale (lcid: 47a): Mapudungun (Chile) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 47c): Mohawk (Canada) - 1252
en_US
English (United States)
windows-1252
OS Locale (lcid: 481): Maori (New Zealand) - 0
mi_NZ
Maori (New Zealand)
UTF-8
OS Locale (lcid: 801): Arabic (Iraq) - 1256
ar_IQ
Arabic (Iraq)
windows-1256
OS Locale (lcid: 804): Chinese (People's Republic of China) - 936
zh_CN
Chinese (China)
GBK
OS Locale (lcid: 807): German (Switzerland) - 1252
de_CH
German (Switzerland)
windows-1252
OS Locale (lcid: 809): English (United Kingdom) - 1252
en_GB
English (United Kingdom)
windows-1252
OS Locale (lcid: 80a): Spanish (Mexico) - 1252
es_MX
Spanish (Mexico)
windows-1252
OS Locale (lcid: 80c): French (Belgium) - 1252
fr_BE
French (Belgium)
windows-1252
OS Locale (lcid: 810): Italian (Switzerland) - 1252
it_CH
Italian (Switzerland)
windows-1252
OS Locale (lcid: 813): Dutch (Belgium) - 1252
nl_BE
Dutch (Belgium)
windows-1252
OS Locale (lcid: 814): Norwegian (Nynorsk) (Norway) - 1252
no_NO_NY
Norwegian (Norway,Nynorsk)
windows-1252
OS Locale (lcid: 816): Portuguese (Portugal) - 1252
pt_PT
Portuguese (Portugal)
windows-1252
OS Locale (lcid: 81a): Serbian (Latin) (Serbia and Montenegro) - 1250
sr_CS
Serbian (Serbia and Montenegro)
windows-1250
OS Locale (lcid: 81d): Swedish (Finland) - 1252
sv_FI
Swedish (Finland)
windows-1252
OS Locale (lcid: 82c): Azeri (Cyrillic) (Azerbaijan) - 1251
az_AZ
Azerbaijani (Azerbaijan)
windows-1251
OS Locale (lcid: 83b): Sami (Northern) (Sweden) - 1252
se_SE
Northern Sami (Sweden)
windows-1252
OS Locale (lcid: 83c): Irish (Ireland) - 1252
ga_IE
Irish (Ireland)
windows-1252
OS Locale (lcid: 83e): Malay (Brunei Darussalam) - 1252
ms_BN
Malay (Brunei)
windows-1252
OS Locale (lcid: 843): Uzbek (Cyrillic) (Uzbekistan) - 1251
uz_UZ
Uzbek (Uzbekistan)
windows-1251
OS Locale (lcid: 85d): Inuktitut (Latin) (Canada) - 1252
iu_CA
Inuktitut (Canada)
windows-1252
OS Locale (lcid: 86b): Quechua (Ecuador) - 1252
qu_EC
Quechua (Ecuador)
windows-1252
OS Locale (lcid: c01): Arabic (Egypt) - 1256
ar_EG
Arabic (Egypt)
windows-1256
OS Locale (lcid: c04): Chinese (Hong Kong S.A.R.) - 950
zh_HK
Chinese (Hong Kong)
x-windows-950
OS Locale (lcid: c07): German (Austria) - 1252
de_AT
German (Austria)
windows-1252
OS Locale (lcid: c09): English (Australia) - 1252
en_AU
English (Australia)
windows-1252
OS Locale (lcid: c0a): Spanish (Spain) - 1252
es_ES
Spanish (Spain)
windows-1252
OS Locale (lcid: c0c): French (Canada) - 1252
fr_CA
French (Canada)
windows-1252
OS Locale (lcid: c1a): Serbian (Cyrillic) (Serbia and Montenegro) - 1251
sr_CS
Serbian (Serbia and Montenegro)
windows-1251
OS Locale (lcid: c3b): Sami (Northern) (Finland) - 1252
se_FI
Northern Sami (Finland)
windows-1252
OS Locale (lcid: c6b): Quechua (Peru) - 1252
qu_PE
Quechua (Peru)
windows-1252
OS Locale (lcid: 1001): Arabic (Libya) - 1256
ar_LY
Arabic (Libya)
windows-1256
OS Locale (lcid: 1004): Chinese (Singapore) - 936
zh_SG
Chinese (Singapore)
GBK
OS Locale (lcid: 1007): German (Luxembourg) - 1252
de_LU
German (Luxembourg)
windows-1252
OS Locale (lcid: 1009): English (Canada) - 1252
en_CA
English (Canada)
windows-1252
OS Locale (lcid: 100a): Spanish (Guatemala) - 1252
es_GT
Spanish (Guatemala)
windows-1252
OS Locale (lcid: 100c): French (Switzerland) - 1252
fr_CH
French (Switzerland)
windows-1252
OS Locale (lcid: 101a): Croatian (Bosnia and Herzegovina) - 1250
hr_BA
Croatian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 103b): Sami (Lule) (Norway) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 1401): Arabic (Algeria) - 1256
ar_DZ
Arabic (Algeria)
windows-1256
OS Locale (lcid: 1404): Chinese (Macau S.A.R.) - 950
zh_MO
Chinese (Macao)
x-windows-950
OS Locale (lcid: 1407): German (Liechtenstein) - 1252
de_LI
German (Liechtenstein)
windows-1252
OS Locale (lcid: 1409): English (New Zealand) - 1252
en_NZ
English (New Zealand)
windows-1252
OS Locale (lcid: 140a): Spanish (Costa Rica) - 1252
es_CR
Spanish (Costa Rica)
windows-1252
OS Locale (lcid: 140c): French (Luxembourg) - 1252
fr_LU
French (Luxembourg)
windows-1252
OS Locale (lcid: 141a): Bosnian (Bosnia and Herzegovina) - 1250
bs_BA
Bosnian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 143b): Sami (Lule) (Sweden) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 1801): Arabic (Morocco) - 1256
ar_MA
Arabic (Morocco)
windows-1256
OS Locale (lcid: 1809): English (Ireland) - 1252
en_IE
English (Ireland)
windows-1252
OS Locale (lcid: 180a): Spanish (Panama) - 1252
es_PA
Spanish (Panama)
windows-1252
OS Locale (lcid: 180c): French (Principality of Monaco) - 1252
fr_MC
French (Monaco)
windows-1252
OS Locale (lcid: 181a): Serbian (Latin) (Bosnia and Herzegovina) - 1250
sr_BA
Serbian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 183b): Sami (Southern) (Norway) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 1c01): Arabic (Tunisia) - 1256
ar_TN
Arabic (Tunisia)
windows-1256
OS Locale (lcid: 1c09): English (South Africa) - 1252
en_ZA
English (South Africa)
windows-1252
OS Locale (lcid: 1c0a): Spanish (Dominican Republic) - 1252
es_DO
Spanish (Dominican Republic)
windows-1252
OS Locale (lcid: 1c1a): Serbian (Cyrillic) (Bosnia and Herzegovina) - 1251
sr_BA
Serbian (Bosnia and Herzegovina)
windows-1251
OS Locale (lcid: 1c3b): Sami (Southern) (Sweden) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 2001): Arabic (Oman) - 1256
ar_OM
Arabic (Oman)
windows-1256
OS Locale (lcid: 2009): English (Jamaica) - 1252
en_JM
English (Jamaica)
windows-1252
OS Locale (lcid: 200a): Spanish (Venezuela) - 1252
es_VE
Spanish (Venezuela)
windows-1252
OS Locale (lcid: 201a): Bosnian (Cyrillic) (Bosnia and Herzegovina) - 1250
bs_BA
Bosnian (Bosnia and Herzegovina)
windows-1250
OS Locale (lcid: 203b): Sami (Skolt) (Finland) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 2401): Arabic (Yemen) - 1256
ar_YE
Arabic (Yemen)
windows-1256
OS Locale (lcid: 2409): English (Caribbean) - 1252
en
English
windows-1252
OS Locale (lcid: 240a): Spanish (Colombia) - 1252
es_CO
Spanish (Colombia)
windows-1252
OS Locale (lcid: 243b): Sami (Inari) (Finland) - 1252
se
Northern Sami
windows-1252
OS Locale (lcid: 2801): Arabic (Syria) - 1256
ar_SY
Arabic (Syria)
windows-1256
OS Locale (lcid: 2809): English (Belize) - 1252
en_BZ
English (Belize)
windows-1252
OS Locale (lcid: 280a): Spanish (Peru) - 1252
es_PE
Spanish (Peru)
windows-1252
OS Locale (lcid: 2c01): Arabic (Jordan) - 1256
ar_JO
Arabic (Jordan)
windows-1256
OS Locale (lcid: 2c09): English (Trinidad and Tobago) - 1252
en_TT
English (Trinidad and Tobago)
windows-1252
OS Locale (lcid: 2c0a): Spanish (Argentina) - 1252
es_AR
Spanish (Argentina)
windows-1252
OS Locale (lcid: 3001): Arabic (Lebanon) - 1256
ar_LB
Arabic (Lebanon)
windows-1256
OS Locale (lcid: 3009): English (Zimbabwe) - 1252
en_ZW
English (Zimbabwe)
windows-1252
OS Locale (lcid: 300a): Spanish (Ecuador) - 1252
es_EC
Spanish (Ecuador)
windows-1252
OS Locale (lcid: 3401): Arabic (Kuwait) - 1256
ar_KW
Arabic (Kuwait)
windows-1256
OS Locale (lcid: 3409): English (Republic of the Philippines) - 1252
en_PH
English (Philippines)
windows-1252
OS Locale (lcid: 340a): Spanish (Chile) - 1252
es_CL
Spanish (Chile)
windows-1252
OS Locale (lcid: 3801): Arabic (U.A.E.) - 1256
ar_AE
Arabic (United Arab Emirates)
windows-1256
OS Locale (lcid: 380a): Spanish (Uruguay) - 1252
es_UY
Spanish (Uruguay)
windows-1252
OS Locale (lcid: 3c01): Arabic (Bahrain) - 1256
ar_BH
Arabic (Bahrain)
windows-1256
OS Locale (lcid: 3c0a): Spanish (Paraguay) - 1252
es_PY
Spanish (Paraguay)
windows-1252
OS Locale (lcid: 4001): Arabic (Qatar) - 1256
ar_QA
Arabic (Qatar)
windows-1256
OS Locale (lcid: 400a): Spanish (Bolivia) - 1252
es_BO
Spanish (Bolivia)
windows-1252
OS Locale (lcid: 440a): Spanish (El Salvador) - 1252
es_SV
Spanish (El Salvador)
windows-1252
OS Locale (lcid: 480a): Spanish (Honduras) - 1252
es_HN
Spanish (Honduras)
windows-1252
OS Locale (lcid: 4c0a): Spanish (Nicaragua) - 1252
es_NI
Spanish (Nicaragua)
windows-1252
OS Locale (lcid: 500a): Spanish (Puerto Rico) - 1252
es_PR
Spanish (Puerto Rico)
windows-1252