269 lines
6.4 KiB
C
Executable File
269 lines
6.4 KiB
C
Executable File
/* -*- 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
|