1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: nlsupport.c,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
33 #pragma warning(push,1) /* disable warnings within system headers */
41 #include <osl/mutex.h>
42 #include <osl/nlsupport.h>
43 #include <osl/diagnose.h>
44 #include <osl/process.h>
45 #include <rtl/tencinfo.h>
47 struct EnumLocalesParams
54 static DWORD g_dwTLSLocaleEncId
= (DWORD
) -1;
56 /*****************************************************************************/
57 /* callback function test
59 /* osl_getTextEncodingFromLocale calls EnumSystemLocalesA, so that we don't
60 /* need to provide a unicode wrapper for this function under Win9x
61 /* that means the callback function has an ansi prototype and receives
62 /* the locale strings as ansi strings
63 /*****************************************************************************/
65 BOOL CALLBACK
EnumLocalesProcA( LPSTR lpLocaleStringA
)
67 struct EnumLocalesParams
* params
;
74 /* convert hex-string to LCID */
75 localeId
= strtol( lpLocaleStringA
, &pszEndA
, 16 );
77 /* check params received via TLS */
78 params
= (struct EnumLocalesParams
*) TlsGetValue( g_dwTLSLocaleEncId
);
79 if( NULL
== params
|| '\0' == params
->Language
[0] )
83 get the ISO language code for this locale
85 remeber: we call the GetLocaleInfoW function
86 because the ansi version of this function returns
87 an error under WinNT/2000 when called with an
90 if( GetLocaleInfo( localeId
, LOCALE_SISO639LANGNAME
, langCode
, 4 ) )
94 /* continue if language code does not match */
95 if( 0 != wcscmp( langCode
, params
->Language
) )
98 /* check if country code is set and equals the current locale */
99 if( '\0' != params
->Country
[0] && GetLocaleInfo( localeId
, LOCALE_SISO3166CTRYNAME
, ctryCode
, 4 ) )
101 /* save return value in TLS and break if found desired locale */
102 if( 0 == wcscmp( ctryCode
, params
->Country
) )
104 params
->Locale
= localeId
;
110 /* fill with default values for that language */
111 LANGID langId
= LANGIDFROMLCID( localeId
);
113 /* exchange sublanguage with SUBLANG_NEUTRAL */
114 langId
= MAKELANGID( PRIMARYLANGID( langId
), SUBLANG_NEUTRAL
);
116 /* and use default sorting order */
117 params
->Locale
= MAKELCID( langId
, SORT_DEFAULT
);
123 /* retry by going on */
128 /*****************************************************************************/
129 /* GetTextEncodingFromLCID
130 /*****************************************************************************/
132 rtl_TextEncoding
GetTextEncodingFromLCID( LCID localeId
)
134 rtl_TextEncoding Encoding
= RTL_TEXTENCODING_DONTKNOW
;
137 /* query ansi codepage for given locale */
138 if( localeId
&& GetLocaleInfo( localeId
, LOCALE_IDEFAULTANSICODEPAGE
, ansiCP
, 6 ) )
140 /* if GetLocaleInfo returns "0", it is a UNICODE only locale */
141 if( 0 != wcscmp( ansiCP
, L
"0" ) )
146 /* values returned from GetLocaleInfo are dezimal based */
147 codepage
= wcstol( ansiCP
, &pwcEnd
, 10 );
149 /* find matching rtl encoding */
150 Encoding
= rtl_getTextEncodingFromWindowsCodePage( codepage
);
153 Encoding
= RTL_TEXTENCODING_UNICODE
;
160 /*****************************************************************************/
161 /* osl_getTextEncodingFromLocale
162 /*****************************************************************************/
164 rtl_TextEncoding SAL_CALL
osl_getTextEncodingFromLocale( rtl_Locale
* pLocale
)
166 struct EnumLocalesParams params
= { L
"", L
"", 0 };
168 /* initialise global TLS id */
169 if( (DWORD
) -1 == g_dwTLSLocaleEncId
)
171 oslMutex globalMutex
= * osl_getGlobalMutex();
173 /* initializing must be thread save */
174 osl_acquireMutex( globalMutex
);
176 if( (DWORD
) -1 == g_dwTLSLocaleEncId
)
177 g_dwTLSLocaleEncId
= TlsAlloc();
179 osl_releaseMutex( globalMutex
);
182 /* if pLocale is NULL, use process locale as default */
183 if( NULL
== pLocale
)
184 osl_getProcessLocale( &pLocale
);
186 /* copy in parameters to structure */
187 if( pLocale
&& pLocale
->Language
)
189 wcscpy( params
.Language
, pLocale
->Language
->buffer
);
191 if( pLocale
->Country
)
192 wcscpy( params
.Country
, pLocale
->Country
->buffer
);
194 /* save pointer to local structure in TLS */
195 TlsSetValue( g_dwTLSLocaleEncId
, ¶ms
);
197 /* enum all locales known to Windows */
198 EnumSystemLocalesA( EnumLocalesProcA
, LCID_SUPPORTED
);
200 /* use the LCID found in iteration */
201 return GetTextEncodingFromLCID( params
.Locale
);
204 return RTL_TEXTENCODING_DONTKNOW
;
207 /*****************************************************************************/
208 /* imp_getProcessLocale
209 /*****************************************************************************/
211 void _imp_getProcessLocale( rtl_Locale
** ppLocale
)
217 OSL_ASSERT( ppLocale
);
219 /* get the LCID to retrieve information from */
220 localeId
= GetUserDefaultLCID();
222 /* call GetLocaleInfo to retrieve the iso codes */
223 if( GetLocaleInfo( localeId
, LOCALE_SISO639LANGNAME
, langCode
, 4 ) &&
224 GetLocaleInfo( localeId
, LOCALE_SISO3166CTRYNAME
, ctryCode
, 4 ) )
226 *ppLocale
= rtl_locale_register( langCode
, ctryCode
, L
"" );
230 *ppLocale
= rtl_locale_register( L
"C", L
"", L
"" );