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