Bump for 3.6-28
[LibreOffice.git] / sal / osl / w32 / nlsupport.c
blob9a4ec7da27df74e7c86777c312aaeee6297ccda5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #define UNICODE
30 #ifdef _MSC_VER
31 #pragma warning(push,1) /* disable warnings within system headers */
32 #endif
33 #include <windows.h>
34 #ifdef _MSC_VER
35 #pragma warning(pop)
36 #endif
37 #include <wchar.h>
39 #include <osl/mutex.h>
40 #include <osl/nlsupport.h>
41 #include <osl/diagnose.h>
42 #include <osl/process.h>
43 #include <rtl/tencinfo.h>
45 struct EnumLocalesParams
47 WCHAR Language[3];
48 WCHAR Country[3];
49 LCID Locale;
52 static DWORD g_dwTLSLocaleEncId = (DWORD) -1;
54 /*****************************************************************************
55 * callback function test
57 * osl_getTextEncodingFromLocale calls EnumSystemLocalesA, so that we don't
58 * need to provide a unicode wrapper for this function under Win9x
59 * that means the callback function has an ansi prototype and receives
60 * the locale strings as ansi strings
61 *****************************************************************************/
63 BOOL CALLBACK EnumLocalesProcA( LPSTR lpLocaleStringA )
65 struct EnumLocalesParams * params;
67 LCID localeId;
68 LPSTR pszEndA;
70 WCHAR langCode[4];
72 /* convert hex-string to LCID */
73 localeId = strtol( lpLocaleStringA, &pszEndA, 16 );
75 /* check params received via TLS */
76 params = (struct EnumLocalesParams *) TlsGetValue( g_dwTLSLocaleEncId );
77 if( NULL == params || '\0' == params->Language[0] )
78 return FALSE;
81 get the ISO language code for this locale
83 remeber: we call the GetLocaleInfoW function
84 because the ansi version of this function returns
85 an error under WinNT/2000 when called with an
86 unicode only lcid
88 if( GetLocaleInfo( localeId, LOCALE_SISO639LANGNAME , langCode, 4 ) )
90 WCHAR ctryCode[4];
92 /* continue if language code does not match */
93 if( 0 != wcscmp( langCode, params->Language ) )
94 return TRUE;
96 /* check if country code is set and equals the current locale */
97 if( '\0' != params->Country[0] && GetLocaleInfo( localeId, LOCALE_SISO3166CTRYNAME , ctryCode, 4 ) )
99 /* save return value in TLS and break if found desired locale */
100 if( 0 == wcscmp( ctryCode, params->Country ) )
102 params->Locale = localeId;
103 return FALSE;
106 else
108 /* fill with default values for that language */
109 LANGID langId = LANGIDFROMLCID( localeId );
111 /* exchange sublanguage with SUBLANG_NEUTRAL */
112 langId = MAKELANGID( PRIMARYLANGID( langId ), SUBLANG_NEUTRAL );
114 /* and use default sorting order */
115 params->Locale = MAKELCID( langId, SORT_DEFAULT );
117 return FALSE;
121 /* retry by going on */
122 return TRUE;
126 /*****************************************************************************
127 * GetTextEncodingFromLCID
128 *****************************************************************************/
130 rtl_TextEncoding GetTextEncodingFromLCID( LCID localeId )
132 rtl_TextEncoding Encoding = RTL_TEXTENCODING_DONTKNOW;
133 WCHAR ansiCP[6];
135 /* query ansi codepage for given locale */
136 if( localeId && GetLocaleInfo( localeId, LOCALE_IDEFAULTANSICODEPAGE, ansiCP, 6 ) )
138 /* if GetLocaleInfo returns "0", it is a UNICODE only locale */
139 if( 0 != wcscmp( ansiCP, L"0" ) )
141 WCHAR *pwcEnd;
142 UINT codepage;
144 /* values returned from GetLocaleInfo are dezimal based */
145 codepage = wcstol( ansiCP, &pwcEnd, 10 );
147 /* find matching rtl encoding */
148 Encoding = rtl_getTextEncodingFromWindowsCodePage( codepage );
150 else
151 Encoding = RTL_TEXTENCODING_UNICODE;
154 return Encoding;
158 /*****************************************************************************
159 * osl_getTextEncodingFromLocale
160 *****************************************************************************/
162 rtl_TextEncoding SAL_CALL osl_getTextEncodingFromLocale( rtl_Locale * pLocale )
164 struct EnumLocalesParams params = { L"", L"", 0 };
166 /* initialise global TLS id */
167 if( (DWORD) -1 == g_dwTLSLocaleEncId )
169 oslMutex globalMutex = * osl_getGlobalMutex();
171 /* initializing must be thread save */
172 osl_acquireMutex( globalMutex );
174 if( (DWORD) -1 == g_dwTLSLocaleEncId )
175 g_dwTLSLocaleEncId = TlsAlloc();
177 osl_releaseMutex( globalMutex );
180 /* if pLocale is NULL, use process locale as default */
181 if( NULL == pLocale )
182 osl_getProcessLocale( &pLocale );
184 /* copy in parameters to structure */
185 if( pLocale && pLocale->Language )
187 wcscpy( params.Language, pLocale->Language->buffer );
189 if( pLocale->Country )
190 wcscpy( params.Country, pLocale->Country->buffer );
192 /* save pointer to local structure in TLS */
193 TlsSetValue( g_dwTLSLocaleEncId, &params );
195 /* enum all locales known to Windows */
196 EnumSystemLocalesA( EnumLocalesProcA, LCID_SUPPORTED );
198 /* use the LCID found in iteration */
199 return GetTextEncodingFromLCID( params.Locale );
202 return RTL_TEXTENCODING_DONTKNOW;
205 /*****************************************************************************
206 * imp_getProcessLocale
207 *****************************************************************************/
209 void _imp_getProcessLocale( rtl_Locale ** ppLocale )
211 WCHAR langCode[4];
212 WCHAR ctryCode[4];
213 LCID localeId;
215 OSL_ASSERT( ppLocale );
217 /* get the LCID to retrieve information from */
218 localeId = GetUserDefaultLCID();
220 /* call GetLocaleInfo to retrieve the iso codes */
221 if( GetLocaleInfo( localeId, LOCALE_SISO639LANGNAME , langCode, 4 ) &&
222 GetLocaleInfo( localeId, LOCALE_SISO3166CTRYNAME , ctryCode, 4 ) )
224 *ppLocale = rtl_locale_register( langCode, ctryCode, L"" );
226 else
228 *ppLocale = rtl_locale_register( L"C", L"", L"" );
233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */