[PATCH] mlang: Handle more RFC1766 Names

Detlef Riekenberg wine.dev at web.de
Sun May 24 12:27:37 CDT 2009


---
 dlls/mlang/mlang.c |   58 +++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/dlls/mlang/mlang.c b/dlls/mlang/mlang.c
index 9cd9a87..9b1e5ac 100644
--- a/dlls/mlang/mlang.c
+++ b/dlls/mlang/mlang.c
@@ -1190,10 +1190,14 @@ HRESULT WINAPI LcidToRfc1766W(
     return S_FALSE;
 }
 
-static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc1766)
+static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc1766, BOOL lazy)
 {
     RFC1766INFO info;
+    WCHAR shortname[MAX_RFC1766_NAME + 1];
     ULONG num;
+    LCID best_lcid = 0;
+    DWORD best_len = 0;
+    LPWSTR ptr;
 
     while (IEnumRfc1766_Next(iface, 1, &info, &num) == S_OK)
     {
@@ -1202,13 +1206,53 @@ static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc176
             *lcid = info.lcid;
             return S_OK;
         }
-        if (strlenW(rfc1766) == 2 && !memcmp(info.wszRfc1766, rfc1766, 2 * sizeof(WCHAR)))
+
+        /* prefer specific name over generic name when the supplied name is not exact*/
+        if (lazy &&
+            lstrlenW(info.wszRfc1766) > best_len &&
+            !strncmpiW(rfc1766, info.wszRfc1766, lstrlenW(info.wszRfc1766)))
         {
-            *lcid = PRIMARYLANGID(info.lcid);
-            return S_OK;
+            best_len = lstrlenW(info.wszRfc1766);
+
+            /* en: SUBLANG_NEUTRAL, others (de, it, fr, ...): SUBLANG_DEFAULT */
+            if (PRIMARYLANGID(info.lcid) == LANG_ENGLISH)
+                best_lcid = LANG_ENGLISH;
+            else
+                best_lcid = info.lcid;
+
+        }
+
+        lstrcpynW(shortname, rfc1766, MAX_RFC1766_NAME);
+        shortname[MAX_RFC1766_NAME] = '\0';
+        ptr = strchrW(shortname, '-');
+        if (lazy && ptr) ptr[0] = 0;
+
+        /* accept language entries (de), when we only have language-country entries (de-de) */
+        if (strlenW(shortname) == 2 && !memcmp(info.wszRfc1766, shortname, 2 * sizeof(WCHAR)))
+        {
+            TRACE("guess lcid 0x%06x: %-9s / %s\n", info.lcid,
+                    debugstr_w(info.wszRfc1766), debugstr_w(info.wszLocaleName));
+
+            if (!best_lcid) {
+                best_len = 2;
+                /* en: SUBLANG_NEUTRAL, others (de, it, fr, ...): SUBLANG_DEFAULT */
+                if (PRIMARYLANGID(info.lcid) == LANG_ENGLISH)
+                    best_lcid = LANG_ENGLISH;
+                else
+                    best_lcid = info.lcid;
+
+            }
         }
     }
 
+    if (best_lcid) {
+        TRACE("=> using lcid: 0x%04x\n", best_lcid);
+
+        *lcid = best_lcid;
+        /* Should return S_FALSE for matched names here.
+           We need locale entries without country (de, it, fr, ..) for this */
+        return S_OK;
+    }
     return E_FAIL;
 }
 
@@ -1226,7 +1270,7 @@ HRESULT WINAPI Rfc1766ToLcidW(LCID *pLocale, LPCWSTR pszRfc1766)
     if (FAILED(hr))
         return hr;
 
-    hr = lcid_from_rfc1766(enumrfc1766, pLocale, pszRfc1766);
+    hr = lcid_from_rfc1766(enumrfc1766, pLocale, pszRfc1766, TRUE);
     IEnumRfc1766_Release(enumrfc1766);
 
     return hr;
@@ -2264,7 +2308,7 @@ static HRESULT WINAPI fnIMultiLanguage_GetLcidFromRfc1766(
     if (FAILED(hr))
         return hr;
 
-    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766);
+    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766, FALSE);
 
     IEnumRfc1766_Release(rfc1766);
     return hr;
@@ -2819,7 +2863,7 @@ static HRESULT WINAPI fnIMultiLanguage2_GetLcidFromRfc1766(
     if (FAILED(hr))
         return hr;
 
-    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766);
+    hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766, FALSE);
 
     IEnumRfc1766_Release(rfc1766);
     return hr;
-- 
1.5.4.3


--=-+RTO9zeV9GJRlnpXKjsH--




More information about the wine-patches mailing list