| /* -*- 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 <windows.h> |
| #include <stdio.h> |
| #include "isocode.h" |
| #include "loclibrary.h" |
| #include "Shlwapi.h" |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <wchar.h> |
| |
| |
| #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 |