1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker *
3*48a54d36SAndroid Build Coastguard Worker * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker *
5*48a54d36SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker *
9*48a54d36SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker *
11*48a54d36SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker */
17*48a54d36SAndroid Build Coastguard Worker
18*48a54d36SAndroid Build Coastguard Worker /* loclibrary.c
19*48a54d36SAndroid Build Coastguard Worker * ----------------------------------------------------------------------
20*48a54d36SAndroid Build Coastguard Worker * Source for localization library
21*48a54d36SAndroid Build Coastguard Worker * Originally created by jsantamaria: 3 may 2004
22*48a54d36SAndroid Build Coastguard Worker * ----------------------------------------------------------------------
23*48a54d36SAndroid Build Coastguard Worker */
24*48a54d36SAndroid Build Coastguard Worker
25*48a54d36SAndroid Build Coastguard Worker #include "DebugServices.h"
26*48a54d36SAndroid Build Coastguard Worker #include <windows.h>
27*48a54d36SAndroid Build Coastguard Worker #include <stdio.h>
28*48a54d36SAndroid Build Coastguard Worker #include "isocode.h"
29*48a54d36SAndroid Build Coastguard Worker #include "loclibrary.h"
30*48a54d36SAndroid Build Coastguard Worker #include "Shlwapi.h"
31*48a54d36SAndroid Build Coastguard Worker #include <sys/types.h>
32*48a54d36SAndroid Build Coastguard Worker #include <sys/stat.h>
33*48a54d36SAndroid Build Coastguard Worker #include <wchar.h>
34*48a54d36SAndroid Build Coastguard Worker
35*48a54d36SAndroid Build Coastguard Worker
36*48a54d36SAndroid Build Coastguard Worker #ifdef __cplusplus
37*48a54d36SAndroid Build Coastguard Worker extern "c" {
38*48a54d36SAndroid Build Coastguard Worker #endif
39*48a54d36SAndroid Build Coastguard Worker
40*48a54d36SAndroid Build Coastguard Worker #ifdef _MSC_VER
41*48a54d36SAndroid Build Coastguard Worker #define swprintf _snwprintf
42*48a54d36SAndroid Build Coastguard Worker #define snprintf _snprintf
43*48a54d36SAndroid Build Coastguard Worker #endif
44*48a54d36SAndroid Build Coastguard Worker
45*48a54d36SAndroid Build Coastguard Worker
46*48a54d36SAndroid Build Coastguard Worker
47*48a54d36SAndroid Build Coastguard Worker #define DEFAULT_LANG_CODE "en"
48*48a54d36SAndroid Build Coastguard Worker
49*48a54d36SAndroid Build Coastguard Worker // gets the user language
_getUserLanguage(void)50*48a54d36SAndroid Build Coastguard Worker static LANGID _getUserLanguage( void ) {
51*48a54d36SAndroid Build Coastguard Worker
52*48a54d36SAndroid Build Coastguard Worker return GetUserDefaultUILanguage();
53*48a54d36SAndroid Build Coastguard Worker
54*48a54d36SAndroid Build Coastguard Worker }
55*48a54d36SAndroid Build Coastguard Worker
56*48a54d36SAndroid Build Coastguard Worker
57*48a54d36SAndroid Build Coastguard Worker // gets the ISO mapping
_getISOCode(LANGID wLangID,char * isoLangCode,int codeLen)58*48a54d36SAndroid Build Coastguard Worker static int _getISOCode(LANGID wLangID, char *isoLangCode, int codeLen) {
59*48a54d36SAndroid Build Coastguard Worker int i;
60*48a54d36SAndroid Build Coastguard Worker unsigned short langCode;
61*48a54d36SAndroid Build Coastguard Worker
62*48a54d36SAndroid Build Coastguard Worker for (i = 0; i < NUM_ISOCODES; i++) {
63*48a54d36SAndroid Build Coastguard Worker int startIndex = i * MODULO_ISOCODES;
64*48a54d36SAndroid Build Coastguard Worker
65*48a54d36SAndroid Build Coastguard Worker langCode = (ISOCODES[startIndex] << 8);
66*48a54d36SAndroid Build Coastguard Worker langCode = langCode + ( (unsigned short) (ISOCODES[startIndex + 1]) );
67*48a54d36SAndroid Build Coastguard Worker
68*48a54d36SAndroid Build Coastguard Worker if (langCode == wLangID) {
69*48a54d36SAndroid Build Coastguard Worker char *langStr = (char *)&(ISOCODES[startIndex+2]);
70*48a54d36SAndroid Build Coastguard Worker strncpy(isoLangCode, langStr, codeLen);
71*48a54d36SAndroid Build Coastguard Worker return 0;
72*48a54d36SAndroid Build Coastguard Worker }
73*48a54d36SAndroid Build Coastguard Worker }
74*48a54d36SAndroid Build Coastguard Worker return 1;
75*48a54d36SAndroid Build Coastguard Worker }
76*48a54d36SAndroid Build Coastguard Worker
77*48a54d36SAndroid Build Coastguard Worker static char isoLangCode[LANG_CODE_LEN + 1] = "";
78*48a54d36SAndroid Build Coastguard Worker static LANGID wLangID = (LANGID) -1;
79*48a54d36SAndroid Build Coastguard Worker
_setLanguageIfNeeded(void)80*48a54d36SAndroid Build Coastguard Worker static void _setLanguageIfNeeded(void) {
81*48a54d36SAndroid Build Coastguard Worker
82*48a54d36SAndroid Build Coastguard Worker // get the language code if we don't have it cached
83*48a54d36SAndroid Build Coastguard Worker if (!strncmp(isoLangCode,"",LANG_CODE_LEN + 1)) {
84*48a54d36SAndroid Build Coastguard Worker
85*48a54d36SAndroid Build Coastguard Worker // if we haven't cached the language id, do the lookup
86*48a54d36SAndroid Build Coastguard Worker if (wLangID == (LANGID) -1) {
87*48a54d36SAndroid Build Coastguard Worker wLangID = _getUserLanguage();
88*48a54d36SAndroid Build Coastguard Worker }
89*48a54d36SAndroid Build Coastguard Worker
90*48a54d36SAndroid Build Coastguard Worker // if no ISOCode, set it to DEFAULT_LANG_CODE
91*48a54d36SAndroid Build Coastguard Worker if (_getISOCode(wLangID, isoLangCode, LANG_CODE_LEN + 1)) {
92*48a54d36SAndroid Build Coastguard Worker strncpy(isoLangCode, DEFAULT_LANG_CODE, LANG_CODE_LEN+1);
93*48a54d36SAndroid Build Coastguard Worker }
94*48a54d36SAndroid Build Coastguard Worker }
95*48a54d36SAndroid Build Coastguard Worker
96*48a54d36SAndroid Build Coastguard Worker }
97*48a54d36SAndroid Build Coastguard Worker
98*48a54d36SAndroid Build Coastguard Worker //// PathForResource
99*48a54d36SAndroid Build Coastguard Worker
100*48a54d36SAndroid Build Coastguard Worker // Gets the PathForResource for handle 0 for the current process
101*48a54d36SAndroid Build Coastguard Worker
102*48a54d36SAndroid Build Coastguard Worker
103*48a54d36SAndroid Build Coastguard Worker static char appPathNameA[MAX_PATH] = "";
104*48a54d36SAndroid Build Coastguard Worker
PathForResourceA(HMODULE module,const char * name,char * locFile,int locFileLen)105*48a54d36SAndroid Build Coastguard Worker int PathForResourceA ( HMODULE module, const char *name, char *locFile, int locFileLen)
106*48a54d36SAndroid Build Coastguard Worker {
107*48a54d36SAndroid Build Coastguard Worker int ret = 0;
108*48a54d36SAndroid Build Coastguard Worker
109*48a54d36SAndroid Build Coastguard Worker if ( !strcmp( appPathNameA, "" ) )
110*48a54d36SAndroid Build Coastguard Worker {
111*48a54d36SAndroid Build Coastguard Worker char folder[MAX_PATH];
112*48a54d36SAndroid Build Coastguard Worker char * ext;
113*48a54d36SAndroid Build Coastguard Worker char * app;
114*48a54d36SAndroid Build Coastguard Worker
115*48a54d36SAndroid Build Coastguard Worker GetModuleFileNameA( module, folder, MAX_PATH );
116*48a54d36SAndroid Build Coastguard Worker
117*48a54d36SAndroid Build Coastguard Worker // Get folder string
118*48a54d36SAndroid Build Coastguard Worker
119*48a54d36SAndroid Build Coastguard Worker app = strrchr( folder, '\\' );
120*48a54d36SAndroid Build Coastguard Worker require_action( app, exit, ret = 0 );
121*48a54d36SAndroid Build Coastguard Worker *app++ = '\0';
122*48a54d36SAndroid Build Coastguard Worker
123*48a54d36SAndroid Build Coastguard Worker // Strip the extension
124*48a54d36SAndroid Build Coastguard Worker
125*48a54d36SAndroid Build Coastguard Worker if ( ( ( ext = strstr( app, ".exe" ) ) != NULL ) || ( ( ext = strstr( app, ".dll" ) ) != NULL ) )
126*48a54d36SAndroid Build Coastguard Worker {
127*48a54d36SAndroid Build Coastguard Worker *ext = '\0';
128*48a54d36SAndroid Build Coastguard Worker }
129*48a54d36SAndroid Build Coastguard Worker
130*48a54d36SAndroid Build Coastguard Worker snprintf( appPathNameA, MAX_PATH, "%s\\%s", folder, app );
131*48a54d36SAndroid Build Coastguard Worker }
132*48a54d36SAndroid Build Coastguard Worker
133*48a54d36SAndroid Build Coastguard Worker ret = PathForResourceWithPathA (appPathNameA, name, locFile, locFileLen);
134*48a54d36SAndroid Build Coastguard Worker
135*48a54d36SAndroid Build Coastguard Worker exit:
136*48a54d36SAndroid Build Coastguard Worker
137*48a54d36SAndroid Build Coastguard Worker return ret;
138*48a54d36SAndroid Build Coastguard Worker }
139*48a54d36SAndroid Build Coastguard Worker
140*48a54d36SAndroid Build Coastguard Worker static wchar_t appPathNameW[MAX_PATH] = L"";
141*48a54d36SAndroid Build Coastguard Worker
PathForResourceW(HMODULE module,const wchar_t * name,wchar_t * locFile,int locFileLen)142*48a54d36SAndroid Build Coastguard Worker int PathForResourceW ( HMODULE module, const wchar_t *name, wchar_t *locFile, int locFileLen)
143*48a54d36SAndroid Build Coastguard Worker {
144*48a54d36SAndroid Build Coastguard Worker int ret = 0;
145*48a54d36SAndroid Build Coastguard Worker
146*48a54d36SAndroid Build Coastguard Worker if ( !wcscmp( appPathNameW, L"" ) )
147*48a54d36SAndroid Build Coastguard Worker {
148*48a54d36SAndroid Build Coastguard Worker wchar_t folder[MAX_PATH];
149*48a54d36SAndroid Build Coastguard Worker wchar_t * app;
150*48a54d36SAndroid Build Coastguard Worker wchar_t * ext;
151*48a54d36SAndroid Build Coastguard Worker
152*48a54d36SAndroid Build Coastguard Worker GetModuleFileNameW( module, folder, MAX_PATH);
153*48a54d36SAndroid Build Coastguard Worker
154*48a54d36SAndroid Build Coastguard Worker // Get folder string
155*48a54d36SAndroid Build Coastguard Worker
156*48a54d36SAndroid Build Coastguard Worker app = wcsrchr( folder, '\\' );
157*48a54d36SAndroid Build Coastguard Worker require_action( app, exit, ret = 0 );
158*48a54d36SAndroid Build Coastguard Worker *app++ = '\0';
159*48a54d36SAndroid Build Coastguard Worker
160*48a54d36SAndroid Build Coastguard Worker // Strip the extension
161*48a54d36SAndroid Build Coastguard Worker
162*48a54d36SAndroid Build Coastguard Worker if ( ( ( ext = wcsstr( app, L".exe" ) ) != NULL ) || ( ( ext = wcsstr( app, L".dll" ) ) != NULL ) )
163*48a54d36SAndroid Build Coastguard Worker {
164*48a54d36SAndroid Build Coastguard Worker *ext = '\0';
165*48a54d36SAndroid Build Coastguard Worker }
166*48a54d36SAndroid Build Coastguard Worker
167*48a54d36SAndroid Build Coastguard Worker swprintf( appPathNameW, MAX_PATH, L"%ls\\%ls", folder, app );
168*48a54d36SAndroid Build Coastguard Worker }
169*48a54d36SAndroid Build Coastguard Worker
170*48a54d36SAndroid Build Coastguard Worker ret = PathForResourceWithPathW (appPathNameW, name, locFile, locFileLen);
171*48a54d36SAndroid Build Coastguard Worker
172*48a54d36SAndroid Build Coastguard Worker exit:
173*48a54d36SAndroid Build Coastguard Worker
174*48a54d36SAndroid Build Coastguard Worker return ret;
175*48a54d36SAndroid Build Coastguard Worker }
176*48a54d36SAndroid Build Coastguard Worker
177*48a54d36SAndroid Build Coastguard Worker
178*48a54d36SAndroid Build Coastguard Worker //// PathForResourceWithPath
179*48a54d36SAndroid Build Coastguard Worker
180*48a54d36SAndroid Build Coastguard Worker #define TMP_BUF_SIZE MAX_PATH
181*48a54d36SAndroid Build Coastguard Worker
PathForResourceWithPathA(const char * path,const char * nm,char * locFile,int locFileLen)182*48a54d36SAndroid Build Coastguard Worker int PathForResourceWithPathA (const char *path, const char *nm,
183*48a54d36SAndroid Build Coastguard Worker char *locFile, int locFileLen) {
184*48a54d36SAndroid Build Coastguard Worker char tmpBuffer[TMP_BUF_SIZE];
185*48a54d36SAndroid Build Coastguard Worker
186*48a54d36SAndroid Build Coastguard Worker // build the path to the executable in the generic
187*48a54d36SAndroid Build Coastguard Worker // resources folder, check there first
188*48a54d36SAndroid Build Coastguard Worker snprintf(tmpBuffer, MAX_PATH, "%s.Resources\\%s", path, nm);
189*48a54d36SAndroid Build Coastguard Worker
190*48a54d36SAndroid Build Coastguard Worker if (!PathFileExistsA(tmpBuffer)) {
191*48a54d36SAndroid Build Coastguard Worker
192*48a54d36SAndroid Build Coastguard Worker // didn't hit generic resource folder, so need to get language codes
193*48a54d36SAndroid Build Coastguard Worker _setLanguageIfNeeded();
194*48a54d36SAndroid Build Coastguard Worker
195*48a54d36SAndroid Build Coastguard Worker // test to see if localized directory exists,
196*48a54d36SAndroid Build Coastguard Worker // if so, we don't fall back if we don't find the file.
197*48a54d36SAndroid Build Coastguard Worker snprintf(tmpBuffer, TMP_BUF_SIZE,
198*48a54d36SAndroid Build Coastguard Worker "%s.Resources\\%s.lproj", path, isoLangCode);
199*48a54d36SAndroid Build Coastguard Worker
200*48a54d36SAndroid Build Coastguard Worker if (PathFileExistsA(tmpBuffer)) {
201*48a54d36SAndroid Build Coastguard Worker snprintf(tmpBuffer, TMP_BUF_SIZE, "%s\\%s", tmpBuffer, nm);
202*48a54d36SAndroid Build Coastguard Worker
203*48a54d36SAndroid Build Coastguard Worker if (!PathFileExistsA(tmpBuffer)) return 0;
204*48a54d36SAndroid Build Coastguard Worker
205*48a54d36SAndroid Build Coastguard Worker strncpy(locFile, tmpBuffer, locFileLen);
206*48a54d36SAndroid Build Coastguard Worker return (int) strlen(locFile);
207*48a54d36SAndroid Build Coastguard Worker }
208*48a54d36SAndroid Build Coastguard Worker
209*48a54d36SAndroid Build Coastguard Worker // fall back on DEFAULT_LANG_CODE if still no good
210*48a54d36SAndroid Build Coastguard Worker snprintf(tmpBuffer, TMP_BUF_SIZE, "%s.Resources\\%s.lproj\\%s",
211*48a54d36SAndroid Build Coastguard Worker path, DEFAULT_LANG_CODE, nm);
212*48a54d36SAndroid Build Coastguard Worker
213*48a54d36SAndroid Build Coastguard Worker // we can't find the resource, so return 0
214*48a54d36SAndroid Build Coastguard Worker if (!PathFileExistsA(tmpBuffer)) return 0;
215*48a54d36SAndroid Build Coastguard Worker }
216*48a54d36SAndroid Build Coastguard Worker
217*48a54d36SAndroid Build Coastguard Worker strncpy(locFile, tmpBuffer, locFileLen);
218*48a54d36SAndroid Build Coastguard Worker return (int) strlen(locFile);
219*48a54d36SAndroid Build Coastguard Worker
220*48a54d36SAndroid Build Coastguard Worker }
221*48a54d36SAndroid Build Coastguard Worker
222*48a54d36SAndroid Build Coastguard Worker
PathForResourceWithPathW(const wchar_t * path,const wchar_t * nm,wchar_t * locFile,int locFileLen)223*48a54d36SAndroid Build Coastguard Worker int PathForResourceWithPathW (const wchar_t *path, const wchar_t *nm,
224*48a54d36SAndroid Build Coastguard Worker wchar_t *locFile, int locFileLen) {
225*48a54d36SAndroid Build Coastguard Worker
226*48a54d36SAndroid Build Coastguard Worker wchar_t tmpBuffer[TMP_BUF_SIZE];
227*48a54d36SAndroid Build Coastguard Worker
228*48a54d36SAndroid Build Coastguard Worker // build the path to the executable in the generic
229*48a54d36SAndroid Build Coastguard Worker // resources folder, check there first
230*48a54d36SAndroid Build Coastguard Worker swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%ls", path, nm);
231*48a54d36SAndroid Build Coastguard Worker
232*48a54d36SAndroid Build Coastguard Worker if (!PathFileExistsW(tmpBuffer)) {
233*48a54d36SAndroid Build Coastguard Worker // didn't hit generic resource folder, so need to get language codes
234*48a54d36SAndroid Build Coastguard Worker _setLanguageIfNeeded();
235*48a54d36SAndroid Build Coastguard Worker
236*48a54d36SAndroid Build Coastguard Worker // test to see if localized directory exists,
237*48a54d36SAndroid Build Coastguard Worker // if so, we don't fall back if we don't find the file.
238*48a54d36SAndroid Build Coastguard Worker swprintf(tmpBuffer, TMP_BUF_SIZE,
239*48a54d36SAndroid Build Coastguard Worker L"%ls.Resources\\%S.lproj", path, isoLangCode);
240*48a54d36SAndroid Build Coastguard Worker
241*48a54d36SAndroid Build Coastguard Worker if (PathFileExistsW(tmpBuffer)) {
242*48a54d36SAndroid Build Coastguard Worker swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls\\%ls", tmpBuffer, nm);
243*48a54d36SAndroid Build Coastguard Worker
244*48a54d36SAndroid Build Coastguard Worker if (!PathFileExistsW(tmpBuffer)) return 0;
245*48a54d36SAndroid Build Coastguard Worker
246*48a54d36SAndroid Build Coastguard Worker wcsncpy(locFile, tmpBuffer, locFileLen);
247*48a54d36SAndroid Build Coastguard Worker return (int) wcslen(locFile);
248*48a54d36SAndroid Build Coastguard Worker }
249*48a54d36SAndroid Build Coastguard Worker
250*48a54d36SAndroid Build Coastguard Worker // fall back on DEFAULT_LANG_CODE if still no good
251*48a54d36SAndroid Build Coastguard Worker swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%S.lproj\\%ls",
252*48a54d36SAndroid Build Coastguard Worker path, DEFAULT_LANG_CODE, nm);
253*48a54d36SAndroid Build Coastguard Worker
254*48a54d36SAndroid Build Coastguard Worker // we can't find the resource, so return 0
255*48a54d36SAndroid Build Coastguard Worker if (!PathFileExistsW(tmpBuffer)) return 0;
256*48a54d36SAndroid Build Coastguard Worker }
257*48a54d36SAndroid Build Coastguard Worker
258*48a54d36SAndroid Build Coastguard Worker wcsncpy(locFile, tmpBuffer, locFileLen);
259*48a54d36SAndroid Build Coastguard Worker return (int) wcslen(locFile);
260*48a54d36SAndroid Build Coastguard Worker
261*48a54d36SAndroid Build Coastguard Worker
262*48a54d36SAndroid Build Coastguard Worker }
263*48a54d36SAndroid Build Coastguard Worker
264*48a54d36SAndroid Build Coastguard Worker
265*48a54d36SAndroid Build Coastguard Worker
266*48a54d36SAndroid Build Coastguard Worker #ifdef __cplusplus
267*48a54d36SAndroid Build Coastguard Worker }
268*48a54d36SAndroid Build Coastguard Worker #endif
269