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