jdk/src/windows/native/java/lang/java_props_md.c
changeset 6489 9e7015635425
parent 5506 202f599c92aa
child 7017 f3bfa15db005
child 6850 56966b0a6a0d
--- a/jdk/src/windows/native/java/lang/java_props_md.c	Mon Aug 23 14:14:52 2010 +0900
+++ b/jdk/src/windows/native/java/lang/java_props_md.c	Tue Aug 31 11:27:10 2010 -0700
@@ -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 *
+getEncodingInternal(LCID lcid)
+{
+    char * ret = malloc(16);
+    int codepage;
 
-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;
+    if (GetLocaleInfo(lcid,
+                      LOCALE_IDEFAULTANSICODEPAGE,
+                      ret+2, 14) == 0) {
+        codepage = 1252;
+    } else {
+        codepage = atoi(ret+2);
+    }
 
-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)
-{
-    char * ret = encoding_names[langIDMap[index].encoding];
+    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 @@
         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 @@
                 strcat(systemPath, "\\FONTS\\SimSun18030.ttc");
                 if ((f = fopen(systemPath, "r")) != NULL) {
                     fclose(f);
-                    ret = "GB18030";
+                    strcpy(ret, "GB18030");
                 }
             }
         }
@@ -489,25 +124,35 @@
 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 @@
     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 @@
          * 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);
-
-            /*
-             * 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 {
-
-                /* 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;
+            char * display_encoding;
 
-                while (*ctry != '_' && *ctry != 0)
-                    ++ctry;
-
-                if (*ctry == '_') {
-                    *ctry++ = 0;
-                }
-
-                variant = ctry;
-                while (*variant != '_' && *variant != 0)
-                    ++variant;
+            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);
 
-                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