update dev300-m58
[ooovba.git] / sal / osl / w32 / nlsupport.c
blobd932f2f0eeff3936b6f3179036637b7630230b0a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: nlsupport.c,v $
10 * $Revision: 1.12 $
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 ************************************************************************/
31 #define UNICODE
32 #ifdef _MSC_VER
33 #pragma warning(push,1) /* disable warnings within system headers */
34 #endif
35 #include <windows.h>
36 #ifdef _MSC_VER
37 #pragma warning(pop)
38 #endif
39 #include <wchar.h>
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
49 WCHAR Language[3];
50 WCHAR Country[3];
51 LCID Locale;
54 static DWORD g_dwTLSLocaleEncId = (DWORD) -1;
56 /*****************************************************************************/
57 /* callback function test
58 /*
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;
69 LCID localeId;
70 LPSTR pszEndA;
72 WCHAR langCode[4];
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] )
80 return FALSE;
82 /*
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
88 unicode only lcid
90 if( GetLocaleInfo( localeId, LOCALE_SISO639LANGNAME , langCode, 4 ) )
92 WCHAR ctryCode[4];
94 /* continue if language code does not match */
95 if( 0 != wcscmp( langCode, params->Language ) )
96 return TRUE;
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;
105 return FALSE;
108 else
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 );
119 return FALSE;
123 /* retry by going on */
124 return TRUE;
128 /*****************************************************************************/
129 /* GetTextEncodingFromLCID
130 /*****************************************************************************/
132 rtl_TextEncoding GetTextEncodingFromLCID( LCID localeId )
134 rtl_TextEncoding Encoding = RTL_TEXTENCODING_DONTKNOW;
135 WCHAR ansiCP[6];
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" ) )
143 WCHAR *pwcEnd;
144 UINT codepage;
146 /* values returned from GetLocaleInfo are dezimal based */
147 codepage = wcstol( ansiCP, &pwcEnd, 10 );
149 /* find matching rtl encoding */
150 Encoding = rtl_getTextEncodingFromWindowsCodePage( codepage );
152 else
153 Encoding = RTL_TEXTENCODING_UNICODE;
156 return Encoding;
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, &params );
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 )
213 WCHAR langCode[4];
214 WCHAR ctryCode[4];
215 LCID localeId;
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"" );
228 else
230 *ppLocale = rtl_locale_register( L"C", L"", L"" );