/* -*- Mode: C; tab-width: 4 -*- * * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* loclibrary.c * ---------------------------------------------------------------------- * Source for localization library * Originally created by jsantamaria: 3 may 2004 * ---------------------------------------------------------------------- */ #include "DebugServices.h" #include #include #include "isocode.h" #include "loclibrary.h" #include "Shlwapi.h" #include #include #include #ifdef __cplusplus extern "c" { #endif #ifdef _MSC_VER #define swprintf _snwprintf #define snprintf _snprintf #endif #define DEFAULT_LANG_CODE "en" // gets the user language static LANGID _getUserLanguage( void ) { return GetUserDefaultUILanguage(); } // gets the ISO mapping static int _getISOCode(LANGID wLangID, char *isoLangCode, int codeLen) { int i; unsigned short langCode; for (i = 0; i < NUM_ISOCODES; i++) { int startIndex = i * MODULO_ISOCODES; langCode = (ISOCODES[startIndex] << 8); langCode = langCode + ( (unsigned short) (ISOCODES[startIndex + 1]) ); if (langCode == wLangID) { char *langStr = (char *)&(ISOCODES[startIndex+2]); strncpy(isoLangCode, langStr, codeLen); return 0; } } return 1; } static char isoLangCode[LANG_CODE_LEN + 1] = ""; static LANGID wLangID = (LANGID) -1; static void _setLanguageIfNeeded(void) { // get the language code if we don't have it cached if (!strncmp(isoLangCode,"",LANG_CODE_LEN + 1)) { // if we haven't cached the language id, do the lookup if (wLangID == (LANGID) -1) { wLangID = _getUserLanguage(); } // if no ISOCode, set it to DEFAULT_LANG_CODE if (_getISOCode(wLangID, isoLangCode, LANG_CODE_LEN + 1)) { strncpy(isoLangCode, DEFAULT_LANG_CODE, LANG_CODE_LEN+1); } } } //// PathForResource // Gets the PathForResource for handle 0 for the current process static char appPathNameA[MAX_PATH] = ""; int PathForResourceA ( HMODULE module, const char *name, char *locFile, int locFileLen) { int ret = 0; if ( !strcmp( appPathNameA, "" ) ) { char folder[MAX_PATH]; char * ext; char * app; GetModuleFileNameA( module, folder, MAX_PATH ); // Get folder string app = strrchr( folder, '\\' ); require_action( app, exit, ret = 0 ); *app++ = '\0'; // Strip the extension if ( ( ( ext = strstr( app, ".exe" ) ) != NULL ) || ( ( ext = strstr( app, ".dll" ) ) != NULL ) ) { *ext = '\0'; } snprintf( appPathNameA, MAX_PATH, "%s\\%s", folder, app ); } ret = PathForResourceWithPathA (appPathNameA, name, locFile, locFileLen); exit: return ret; } static wchar_t appPathNameW[MAX_PATH] = L""; int PathForResourceW ( HMODULE module, const wchar_t *name, wchar_t *locFile, int locFileLen) { int ret = 0; if ( !wcscmp( appPathNameW, L"" ) ) { wchar_t folder[MAX_PATH]; wchar_t * app; wchar_t * ext; GetModuleFileNameW( module, folder, MAX_PATH); // Get folder string app = wcsrchr( folder, '\\' ); require_action( app, exit, ret = 0 ); *app++ = '\0'; // Strip the extension if ( ( ( ext = wcsstr( app, L".exe" ) ) != NULL ) || ( ( ext = wcsstr( app, L".dll" ) ) != NULL ) ) { *ext = '\0'; } swprintf( appPathNameW, MAX_PATH, L"%ls\\%ls", folder, app ); } ret = PathForResourceWithPathW (appPathNameW, name, locFile, locFileLen); exit: return ret; } //// PathForResourceWithPath #define TMP_BUF_SIZE MAX_PATH int PathForResourceWithPathA (const char *path, const char *nm, char *locFile, int locFileLen) { char tmpBuffer[TMP_BUF_SIZE]; // build the path to the executable in the generic // resources folder, check there first snprintf(tmpBuffer, MAX_PATH, "%s.Resources\\%s", path, nm); if (!PathFileExistsA(tmpBuffer)) { // didn't hit generic resource folder, so need to get language codes _setLanguageIfNeeded(); // test to see if localized directory exists, // if so, we don't fall back if we don't find the file. snprintf(tmpBuffer, TMP_BUF_SIZE, "%s.Resources\\%s.lproj", path, isoLangCode); if (PathFileExistsA(tmpBuffer)) { snprintf(tmpBuffer, TMP_BUF_SIZE, "%s\\%s", tmpBuffer, nm); if (!PathFileExistsA(tmpBuffer)) return 0; strncpy(locFile, tmpBuffer, locFileLen); return (int) strlen(locFile); } // fall back on DEFAULT_LANG_CODE if still no good snprintf(tmpBuffer, TMP_BUF_SIZE, "%s.Resources\\%s.lproj\\%s", path, DEFAULT_LANG_CODE, nm); // we can't find the resource, so return 0 if (!PathFileExistsA(tmpBuffer)) return 0; } strncpy(locFile, tmpBuffer, locFileLen); return (int) strlen(locFile); } int PathForResourceWithPathW (const wchar_t *path, const wchar_t *nm, wchar_t *locFile, int locFileLen) { wchar_t tmpBuffer[TMP_BUF_SIZE]; // build the path to the executable in the generic // resources folder, check there first swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%ls", path, nm); if (!PathFileExistsW(tmpBuffer)) { // didn't hit generic resource folder, so need to get language codes _setLanguageIfNeeded(); // test to see if localized directory exists, // if so, we don't fall back if we don't find the file. swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%S.lproj", path, isoLangCode); if (PathFileExistsW(tmpBuffer)) { swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls\\%ls", tmpBuffer, nm); if (!PathFileExistsW(tmpBuffer)) return 0; wcsncpy(locFile, tmpBuffer, locFileLen); return (int) wcslen(locFile); } // fall back on DEFAULT_LANG_CODE if still no good swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%S.lproj\\%ls", path, DEFAULT_LANG_CODE, nm); // we can't find the resource, so return 0 if (!PathFileExistsW(tmpBuffer)) return 0; } wcsncpy(locFile, tmpBuffer, locFileLen); return (int) wcslen(locFile); } #ifdef __cplusplus } #endif