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 50 static LANGID _getUserLanguage( void ) { 51 52 return GetUserDefaultUILanguage(); 53 54 } 55 56 57 // gets the ISO mapping 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 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 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 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 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 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