1647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3647f063dSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4647f063dSAndrew Rist * or more contributor license agreements. See the NOTICE file
5647f063dSAndrew Rist * distributed with this work for additional information
6647f063dSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7647f063dSAndrew Rist * to you under the Apache License, Version 2.0 (the
8647f063dSAndrew Rist * "License"); you may not use this file except in compliance
9647f063dSAndrew Rist * with the License. You may obtain a copy of the License at
10647f063dSAndrew Rist *
11647f063dSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12647f063dSAndrew Rist *
13647f063dSAndrew Rist * Unless required by applicable law or agreed to in writing,
14647f063dSAndrew Rist * software distributed under the License is distributed on an
15647f063dSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16647f063dSAndrew Rist * KIND, either express or implied. See the License for the
17647f063dSAndrew Rist * specific language governing permissions and limitations
18647f063dSAndrew Rist * under the License.
19647f063dSAndrew Rist *
20647f063dSAndrew Rist *************************************************************/
21647f063dSAndrew Rist
22647f063dSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #define UNICODE
25cdf0e10cSrcweir #ifdef _MSC_VER
26cdf0e10cSrcweir #pragma warning(push,1) /* disable warnings within system headers */
27cdf0e10cSrcweir #endif
28cdf0e10cSrcweir #include <windows.h>
29cdf0e10cSrcweir #ifdef _MSC_VER
30cdf0e10cSrcweir #pragma warning(pop)
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #include <wchar.h>
33cdf0e10cSrcweir
34cdf0e10cSrcweir #include <osl/mutex.h>
35cdf0e10cSrcweir #include <osl/nlsupport.h>
36cdf0e10cSrcweir #include <osl/diagnose.h>
37cdf0e10cSrcweir #include <osl/process.h>
38cdf0e10cSrcweir #include <rtl/tencinfo.h>
39cdf0e10cSrcweir
40cdf0e10cSrcweir struct EnumLocalesParams
41cdf0e10cSrcweir {
42cdf0e10cSrcweir WCHAR Language[3];
43cdf0e10cSrcweir WCHAR Country[3];
44cdf0e10cSrcweir LCID Locale;
45cdf0e10cSrcweir };
46cdf0e10cSrcweir
47cdf0e10cSrcweir static DWORD g_dwTLSLocaleEncId = (DWORD) -1;
48cdf0e10cSrcweir
49cdf0e10cSrcweir /*****************************************************************************/
50cdf0e10cSrcweir /* callback function test
51cdf0e10cSrcweir /*
52cdf0e10cSrcweir /* osl_getTextEncodingFromLocale calls EnumSystemLocalesA, so that we don't
53cdf0e10cSrcweir /* need to provide a unicode wrapper for this function under Win9x
54cdf0e10cSrcweir /* that means the callback function has an ansi prototype and receives
55cdf0e10cSrcweir /* the locale strings as ansi strings
56cdf0e10cSrcweir /*****************************************************************************/
57cdf0e10cSrcweir
EnumLocalesProcA(LPSTR lpLocaleStringA)58cdf0e10cSrcweir BOOL CALLBACK EnumLocalesProcA( LPSTR lpLocaleStringA )
59cdf0e10cSrcweir {
60cdf0e10cSrcweir struct EnumLocalesParams * params;
61cdf0e10cSrcweir
62cdf0e10cSrcweir LCID localeId;
63cdf0e10cSrcweir LPSTR pszEndA;
64cdf0e10cSrcweir
65cdf0e10cSrcweir WCHAR langCode[4];
66cdf0e10cSrcweir
67cdf0e10cSrcweir /* convert hex-string to LCID */
68cdf0e10cSrcweir localeId = strtol( lpLocaleStringA, &pszEndA, 16 );
69cdf0e10cSrcweir
70cdf0e10cSrcweir /* check params received via TLS */
71cdf0e10cSrcweir params = (struct EnumLocalesParams *) TlsGetValue( g_dwTLSLocaleEncId );
72cdf0e10cSrcweir if( NULL == params || '\0' == params->Language[0] )
73cdf0e10cSrcweir return FALSE;
74cdf0e10cSrcweir
75cdf0e10cSrcweir /*
76cdf0e10cSrcweir get the ISO language code for this locale
77cdf0e10cSrcweir
78*86e1cf34SPedro Giffuni remember: we call the GetLocaleInfoW function
79cdf0e10cSrcweir because the ansi version of this function returns
80cdf0e10cSrcweir an error under WinNT/2000 when called with an
81cdf0e10cSrcweir unicode only lcid
82cdf0e10cSrcweir */
83cdf0e10cSrcweir if( GetLocaleInfo( localeId, LOCALE_SISO639LANGNAME , langCode, 4 ) )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir WCHAR ctryCode[4];
86cdf0e10cSrcweir
87cdf0e10cSrcweir /* continue if language code does not match */
88cdf0e10cSrcweir if( 0 != wcscmp( langCode, params->Language ) )
89cdf0e10cSrcweir return TRUE;
90cdf0e10cSrcweir
91cdf0e10cSrcweir /* check if country code is set and equals the current locale */
92cdf0e10cSrcweir if( '\0' != params->Country[0] && GetLocaleInfo( localeId, LOCALE_SISO3166CTRYNAME , ctryCode, 4 ) )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir /* save return value in TLS and break if found desired locale */
95cdf0e10cSrcweir if( 0 == wcscmp( ctryCode, params->Country ) )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir params->Locale = localeId;
98cdf0e10cSrcweir return FALSE;
99cdf0e10cSrcweir }
100cdf0e10cSrcweir }
101cdf0e10cSrcweir else
102cdf0e10cSrcweir {
103cdf0e10cSrcweir /* fill with default values for that language */
104cdf0e10cSrcweir LANGID langId = LANGIDFROMLCID( localeId );
105cdf0e10cSrcweir
106cdf0e10cSrcweir /* exchange sublanguage with SUBLANG_NEUTRAL */
107cdf0e10cSrcweir langId = MAKELANGID( PRIMARYLANGID( langId ), SUBLANG_NEUTRAL );
108cdf0e10cSrcweir
109cdf0e10cSrcweir /* and use default sorting order */
110cdf0e10cSrcweir params->Locale = MAKELCID( langId, SORT_DEFAULT );
111cdf0e10cSrcweir
112cdf0e10cSrcweir return FALSE;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir
116cdf0e10cSrcweir /* retry by going on */
117cdf0e10cSrcweir return TRUE;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir
120cdf0e10cSrcweir
121cdf0e10cSrcweir /*****************************************************************************/
122cdf0e10cSrcweir /* GetTextEncodingFromLCID
123cdf0e10cSrcweir /*****************************************************************************/
124cdf0e10cSrcweir
GetTextEncodingFromLCID(LCID localeId)125cdf0e10cSrcweir rtl_TextEncoding GetTextEncodingFromLCID( LCID localeId )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir rtl_TextEncoding Encoding = RTL_TEXTENCODING_DONTKNOW;
128cdf0e10cSrcweir WCHAR ansiCP[6];
129cdf0e10cSrcweir
130cdf0e10cSrcweir /* query ansi codepage for given locale */
131cdf0e10cSrcweir if( localeId && GetLocaleInfo( localeId, LOCALE_IDEFAULTANSICODEPAGE, ansiCP, 6 ) )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir /* if GetLocaleInfo returns "0", it is a UNICODE only locale */
134cdf0e10cSrcweir if( 0 != wcscmp( ansiCP, L"0" ) )
135cdf0e10cSrcweir {
136cdf0e10cSrcweir WCHAR *pwcEnd;
137cdf0e10cSrcweir UINT codepage;
138cdf0e10cSrcweir
139cdf0e10cSrcweir /* values returned from GetLocaleInfo are dezimal based */
140cdf0e10cSrcweir codepage = wcstol( ansiCP, &pwcEnd, 10 );
141cdf0e10cSrcweir
142cdf0e10cSrcweir /* find matching rtl encoding */
143cdf0e10cSrcweir Encoding = rtl_getTextEncodingFromWindowsCodePage( codepage );
144cdf0e10cSrcweir }
145cdf0e10cSrcweir else
146cdf0e10cSrcweir Encoding = RTL_TEXTENCODING_UNICODE;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir
149cdf0e10cSrcweir return Encoding;
150cdf0e10cSrcweir }
151cdf0e10cSrcweir
152cdf0e10cSrcweir
153cdf0e10cSrcweir /*****************************************************************************/
154cdf0e10cSrcweir /* osl_getTextEncodingFromLocale
155cdf0e10cSrcweir /*****************************************************************************/
156cdf0e10cSrcweir
osl_getTextEncodingFromLocale(rtl_Locale * pLocale)157cdf0e10cSrcweir rtl_TextEncoding SAL_CALL osl_getTextEncodingFromLocale( rtl_Locale * pLocale )
158cdf0e10cSrcweir {
159cdf0e10cSrcweir struct EnumLocalesParams params = { L"", L"", 0 };
160cdf0e10cSrcweir
161cdf0e10cSrcweir /* initialise global TLS id */
162cdf0e10cSrcweir if( (DWORD) -1 == g_dwTLSLocaleEncId )
163cdf0e10cSrcweir {
164cdf0e10cSrcweir oslMutex globalMutex = * osl_getGlobalMutex();
165cdf0e10cSrcweir
166cdf0e10cSrcweir /* initializing must be thread save */
167cdf0e10cSrcweir osl_acquireMutex( globalMutex );
168cdf0e10cSrcweir
169cdf0e10cSrcweir if( (DWORD) -1 == g_dwTLSLocaleEncId )
170cdf0e10cSrcweir g_dwTLSLocaleEncId = TlsAlloc();
171cdf0e10cSrcweir
172cdf0e10cSrcweir osl_releaseMutex( globalMutex );
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
175cdf0e10cSrcweir /* if pLocale is NULL, use process locale as default */
176cdf0e10cSrcweir if( NULL == pLocale )
177cdf0e10cSrcweir osl_getProcessLocale( &pLocale );
178cdf0e10cSrcweir
179cdf0e10cSrcweir /* copy in parameters to structure */
180cdf0e10cSrcweir if( pLocale && pLocale->Language )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir wcscpy( params.Language, pLocale->Language->buffer );
183cdf0e10cSrcweir
184cdf0e10cSrcweir if( pLocale->Country )
185cdf0e10cSrcweir wcscpy( params.Country, pLocale->Country->buffer );
186cdf0e10cSrcweir
187cdf0e10cSrcweir /* save pointer to local structure in TLS */
188cdf0e10cSrcweir TlsSetValue( g_dwTLSLocaleEncId, ¶ms );
189cdf0e10cSrcweir
190cdf0e10cSrcweir /* enum all locales known to Windows */
191cdf0e10cSrcweir EnumSystemLocalesA( EnumLocalesProcA, LCID_SUPPORTED );
192cdf0e10cSrcweir
193cdf0e10cSrcweir /* use the LCID found in iteration */
194cdf0e10cSrcweir return GetTextEncodingFromLCID( params.Locale );
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
197cdf0e10cSrcweir return RTL_TEXTENCODING_DONTKNOW;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
200cdf0e10cSrcweir /*****************************************************************************/
201cdf0e10cSrcweir /* imp_getProcessLocale
202cdf0e10cSrcweir /*****************************************************************************/
203cdf0e10cSrcweir
_imp_getProcessLocale(rtl_Locale ** ppLocale)204cdf0e10cSrcweir void _imp_getProcessLocale( rtl_Locale ** ppLocale )
205cdf0e10cSrcweir {
206cdf0e10cSrcweir WCHAR langCode[4];
207cdf0e10cSrcweir WCHAR ctryCode[4];
208cdf0e10cSrcweir LCID localeId;
209cdf0e10cSrcweir
210cdf0e10cSrcweir OSL_ASSERT( ppLocale );
211cdf0e10cSrcweir
212cdf0e10cSrcweir /* get the LCID to retrieve information from */
213cdf0e10cSrcweir localeId = GetUserDefaultLCID();
214cdf0e10cSrcweir
215cdf0e10cSrcweir /* call GetLocaleInfo to retrieve the iso codes */
216cdf0e10cSrcweir if( GetLocaleInfo( localeId, LOCALE_SISO639LANGNAME , langCode, 4 ) &&
217cdf0e10cSrcweir GetLocaleInfo( localeId, LOCALE_SISO3166CTRYNAME , ctryCode, 4 ) )
218cdf0e10cSrcweir {
219cdf0e10cSrcweir *ppLocale = rtl_locale_register( langCode, ctryCode, L"" );
220cdf0e10cSrcweir }
221cdf0e10cSrcweir else
222cdf0e10cSrcweir {
223cdf0e10cSrcweir *ppLocale = rtl_locale_register( L"C", L"", L"" );
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir
228