From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/langpack/langpack.cpp | 569 ++++++++++++++++++++++++++++++++++++ src/modules/langpack/lpservices.cpp | 168 +++++++++++ 2 files changed, 737 insertions(+) create mode 100644 src/modules/langpack/langpack.cpp create mode 100644 src/modules/langpack/lpservices.cpp (limited to 'src/modules/langpack') diff --git a/src/modules/langpack/langpack.cpp b/src/modules/langpack/langpack.cpp new file mode 100644 index 0000000000..0603a24b90 --- /dev/null +++ b/src/modules/langpack/langpack.cpp @@ -0,0 +1,569 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "commonheaders.h" + +#include "../netlib/netlib.h" + +#define LANGPACK_BUF_SIZE 4000 + +int LoadLangPackServices(void); + +struct LangPackMuuid +{ + MUUID muuid; + PLUGININFOEX* pInfo; +}; + +static int CompareMuuids( const LangPackMuuid* p1, const LangPackMuuid* p2 ) +{ + return memcmp( &p1->muuid, &p2->muuid, sizeof( MUUID )); +} + +static LIST lMuuids( 10, CompareMuuids ); +static LangPackMuuid* pCurrentMuuid = NULL; + +static BOOL bModuleInitialized = FALSE; + +struct LangPackEntry { + DWORD englishHash; + char *local; + wchar_t *wlocal; + LangPackMuuid* pMuuid; + LangPackEntry* pNext; // for langpack items with the same hash value +}; + +struct LangPackStruct { + TCHAR filename[MAX_PATH]; + TCHAR filePath[MAX_PATH]; + char language[64]; + char lastModifiedUsing[64]; + char authors[256]; + char authorEmail[128]; + LangPackEntry *entry; + int entryCount, entriesAlloced; + LCID localeID; + UINT defaultANSICp; +} static langPack; + +static int IsEmpty(char *str) +{ + int i = 0; + + while (str[i]) + { + if (str[i]!=' '&&str[i]!='\r'&&str[i]!='\n') + return 0; + i++; + } + return 1; +} + +void ConvertBackslashes(char *str, UINT fileCp) +{ + char *pstr; + for ( pstr = str; *pstr; pstr = CharNextExA( fileCp, pstr, 0 )) { + if( *pstr == '\\' ) { + switch( pstr[1] ) { + case 'n': *pstr = '\n'; break; + case 't': *pstr = '\t'; break; + case 'r': *pstr = '\r'; break; + default: *pstr = pstr[1]; break; + } + memmove(pstr+1, pstr+2, strlen(pstr+2) + 1); +} } } + +#ifdef _DEBUG +//#pragma optimize( "gt", on ) +#endif + +// MurmurHash2 +unsigned int __fastcall hash(const void * key, unsigned int len) +{ + // 'm' and 'r' are mixing constants generated offline. + // They're not really 'magic', they just happen to work well. + const unsigned int m = 0x5bd1e995; + const int r = 24; + + // Initialize the hash to a 'random' value + unsigned int h = len; + + // Mix 4 bytes at a time into the hash + const unsigned char * data = (const unsigned char *)key; + + while(len >= 4) + { + unsigned int k = *(unsigned int *)data; + + k *= m; + k ^= k >> r; + k *= m; + + h *= m; + h ^= k; + + data += 4; + len -= 4; + } + + // Handle the last few bytes of the input array + switch(len) + { + case 3: h ^= data[2] << 16; + case 2: h ^= data[1] << 8; + case 1: h ^= data[0]; + h *= m; + }; + + // Do a few final mixes of the hash to ensure the last few + // bytes are well-incorporated. + h ^= h >> 13; + h *= m; + h ^= h >> 15; + + return h; +} + +unsigned int __fastcall hashstrW(const char * key) +{ + if (key == NULL) return 0; + const unsigned int len = (unsigned int)wcslen((const wchar_t*)key); + char* buf = (char*)alloca(len + 1); + for (unsigned i = 0; i <= len ; ++i) + buf[i] = key[i << 1]; + return hash(buf, len); +} + +static int SortLangPackHashesProc(LangPackEntry *arg1,LangPackEntry *arg2) +{ + if (arg1->englishHash < arg2->englishHash) return -1; + if (arg1->englishHash > arg2->englishHash) return 1; + + return (arg1->pMuuid < arg2->pMuuid) ? -1 : 1; +} + +static void swapBytes( void* p, size_t iSize ) +{ + char *head = (char *)p; // here + char *tail = head + iSize - 1; + + for (; tail > head; --tail, ++head) { + char temp = *head; + *head = *tail; + *tail = temp; + } +} + +static bool EnterMuuid( const char* p, MUUID& result ) +{ + if ( *p++ != '{' ) + return false; + + BYTE* d = (BYTE*)&result; + + for ( int nBytes = 0; *p && nBytes < 24; p++ ) { + if ( *p == '-' ) + continue; + + if ( *p == '}' ) + break; + + if ( !isxdigit( *p )) + return false; + + if ( !isxdigit( p[1] )) + return false; + + int c = 0; + if ( sscanf( p, "%2x", &c ) != 1 ) + return false; + + *d++ = ( BYTE )c; + nBytes++; + p++; + } + + if ( *p != '}' ) + return false; + + swapBytes( &result.a, sizeof( result.a )); + swapBytes( &result.b, sizeof( result.b )); + swapBytes( &result.c, sizeof( result.c )); + return true; +} + +static void LoadLangPackFile( FILE* fp, char* line, UINT fileCp ) +{ + while ( !feof( fp )) { + if ( fgets( line, LANGPACK_BUF_SIZE, fp ) == NULL ) + break; + + if ( IsEmpty(line) || line[0] == ';' || line[0] == 0 ) + continue; + + rtrim( line ); + + if ( line[0] == '#' ) { + strlwr( line ); + + if ( !memcmp( line+1, "include", 7 )) { + TCHAR tszFileName[ MAX_PATH ]; + TCHAR* fileName = mir_a2t( ltrim( line+9 )); + mir_sntprintf( tszFileName, SIZEOF(tszFileName), _T("%s%s"), langPack.filePath, fileName ); + mir_free( fileName ); + + FILE* p = _tfopen( tszFileName, _T("r")); + if ( p ) { + line[0] = 0; + fgets( line, SIZEOF(line), p ); + + UINT fileCp = CP_ACP; + if (strlen(line) >= 3 && line[0]=='\xef' && line[1]=='\xbb' && line[2]=='\xbf') + { + fileCp = CP_UTF8; + fseek(p, 3, SEEK_SET); + } + else + { + fileCp = langPack.defaultANSICp; + fseek(p, 0, SEEK_SET); + } + + LoadLangPackFile( p, line, fileCp ); + fclose( p ); + } + } + else if ( !memcmp( line+1, "muuid", 5 )) { + MUUID t; + if ( !EnterMuuid( line+7, t )) { + NetlibLogf( NULL, "Invalid MUUID: %s\n", line+7 ); + continue; + } + + LangPackMuuid* pNew = ( LangPackMuuid* )mir_alloc( sizeof( LangPackMuuid )); + memcpy( &pNew->muuid, &t, sizeof( t )); + pNew->pInfo = NULL; + lMuuids.insert( pNew ); + pCurrentMuuid = pNew; + } + + continue; + } + + ConvertBackslashes( line, fileCp ); + + if ( line[0] == '[' && line[ lstrlenA(line)-1 ] == ']' ) { + if ( langPack.entryCount && langPack.entry[ langPack.entryCount-1].local == NULL ) + langPack.entryCount--; + + char* pszLine = line+1; + line[ lstrlenA(line)-1 ] = '\0'; + if ( ++langPack.entryCount > langPack.entriesAlloced ) { + langPack.entriesAlloced += 128; + langPack.entry = ( LangPackEntry* )mir_realloc( langPack.entry, sizeof(LangPackEntry)*langPack.entriesAlloced ); + } + + LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; + E->englishHash = hashstr(pszLine); + E->local = NULL; + E->wlocal = NULL; + E->pMuuid = pCurrentMuuid; + E->pNext = NULL; + continue; + } + + if ( !langPack.entryCount ) + continue; + + LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; + if ( E->local == NULL ) { + E->local = mir_strdup( line ); + if ( fileCp == CP_UTF8 ) + Utf8DecodeCP( E->local, langPack.defaultANSICp, NULL ); + + int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); + E->wlocal = (wchar_t *)mir_alloc((iNeeded+1) * sizeof(wchar_t)); + MultiByteToWideChar( fileCp, 0, line, -1, E->wlocal, iNeeded ); + } + else { + size_t iOldLenA = strlen( E->local ); + E->local = ( char* )mir_realloc( E->local, iOldLenA + strlen(line) + 2 ); + strcat( E->local, "\n" ); + strcat( E->local, line ); + + if ( fileCp == CP_UTF8 ) + Utf8DecodeCP( E->local + iOldLenA + 1, langPack.defaultANSICp, NULL ); + + int iNeeded = MultiByteToWideChar( fileCp, 0, line, -1, 0, 0 ); + size_t iOldLen = wcslen( E->wlocal ); + E->wlocal = ( wchar_t* )mir_realloc( E->wlocal, ( sizeof(wchar_t) * ( iOldLen + iNeeded + 2))); + wcscat( E->wlocal, L"\n" ); + MultiByteToWideChar( fileCp, 0, line, -1, E->wlocal + iOldLen + 1, iNeeded ); + } + } +} + +static int LoadLangPack(const TCHAR *szLangPack) +{ + int startOfLine=0; + USHORT langID; + + lstrcpy( langPack.filename, szLangPack ); + lstrcpy( langPack.filePath, szLangPack ); + TCHAR* p = _tcsrchr( langPack.filePath, '\\' ); + if ( p ) + p[1] = 0; + + FILE *fp = _tfopen(szLangPack,_T("rt")); + if ( fp == NULL ) + return 1; + + char line[ LANGPACK_BUF_SIZE ] = ""; + fgets( line, SIZEOF(line), fp ); + + UINT fileCp = CP_ACP; + size_t lineLen = strlen(line); + if (lineLen >= 3 && line[0]=='\xef' && line[1]=='\xbb' && line[2]=='\xbf') + { + fileCp = CP_UTF8; + memmove(line, line + 3, lineLen - 2); + } + + lrtrim( line ); + if ( lstrcmpA( line, "Miranda Language Pack Version 1" )) { + fclose(fp); + return 2; + } + + //headers + while ( !feof( fp )) { + startOfLine = ftell( fp ); + if ( fgets( line, SIZEOF(line), fp ) == NULL ) + break; + + lrtrim( line ); + if( IsEmpty( line ) || line[0]==';' || line[0]==0) + continue; + + if ( line[0] == '[' || line[0] == '#' ) + break; + + char* pszColon = strchr( line,':' ); + if ( pszColon == NULL ) { + fclose( fp ); + return 3; + } + + *pszColon++ = 0; + if(!lstrcmpA(line,"Language")) {mir_snprintf(langPack.language,sizeof(langPack.language),"%s",pszColon); lrtrim(langPack.language);} + else if(!lstrcmpA(line,"Last-Modified-Using")) {mir_snprintf(langPack.lastModifiedUsing,sizeof(langPack.lastModifiedUsing),"%s",pszColon); lrtrim(langPack.lastModifiedUsing);} + else if(!lstrcmpA(line,"Authors")) {mir_snprintf(langPack.authors,sizeof(langPack.authors),"%s",pszColon); lrtrim(langPack.authors);} + else if(!lstrcmpA(line,"Author-email")) {mir_snprintf(langPack.authorEmail,sizeof(langPack.authorEmail),"%s",pszColon); lrtrim(langPack.authorEmail);} + else if(!lstrcmpA(line, "Locale")) { + char szBuf[20], *stopped; + + lrtrim(pszColon + 1); + langID = (USHORT)strtol(pszColon, &stopped, 16); + langPack.localeID = MAKELCID(langID, 0); + GetLocaleInfoA(langPack.localeID, LOCALE_IDEFAULTANSICODEPAGE, szBuf, 10); + szBuf[5] = 0; // codepages have max. 5 digits + langPack.defaultANSICp = atoi(szBuf); + if (fileCp == CP_ACP) + fileCp = langPack.defaultANSICp; + } + } + + //body + fseek( fp, startOfLine, SEEK_SET ); + langPack.entriesAlloced = 0; + + LoadLangPackFile( fp, line, fileCp ); + fclose(fp); + + qsort(langPack.entry,langPack.entryCount,sizeof(LangPackEntry),(int(*)(const void*,const void*))SortLangPackHashesProc); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static int SortLangPackHashesProc2(LangPackEntry *arg1,LangPackEntry *arg2) +{ + if (arg1->englishHash < arg2->englishHash) return -1; + if (arg1->englishHash > arg2->englishHash) return 1; + return 0; +} + +char *LangPackTranslateString(LangPackMuuid* pUuid, const char *szEnglish, const int W) +{ + if ( langPack.entryCount == 0 || szEnglish == NULL ) + return (char*)szEnglish; + + LangPackEntry key,*entry; + key.englishHash = W ? hashstrW(szEnglish) : hashstr(szEnglish); + entry = (LangPackEntry*)bsearch(&key, langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*,const void*))SortLangPackHashesProc2 ); + if ( entry == NULL ) + return (char*)szEnglish; + + // try to find the exact match, otherwise the first entry will be returned + if ( pUuid ) { + for ( LangPackEntry* p = entry->pNext; p != NULL; p = p->pNext ) { + if (p->pMuuid == pUuid) { + entry = p; + break; + } } } + + return W ? (char *)entry->wlocal : entry->local; +} + +int LangPackGetDefaultCodePage() +{ + return langPack.defaultANSICp; +} + +int LangPackGetDefaultLocale() +{ + return (langPack.localeID == 0) ? LOCALE_USER_DEFAULT : langPack.localeID; +} + +TCHAR* LangPackPcharToTchar( const char* pszStr ) +{ + if ( pszStr == NULL ) + return NULL; + + #if defined( _UNICODE ) + { int len = (int)strlen( pszStr ); + TCHAR* result = ( TCHAR* )alloca(( len+1 )*sizeof( TCHAR )); + MultiByteToWideChar( LangPackGetDefaultCodePage(), 0, pszStr, -1, result, len ); + result[len] = 0; + return mir_wstrdup( TranslateW( result )); + } + #else + return mir_strdup( Translate( pszStr )); + #endif +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LangPackMuuid* __fastcall LangPackLookupUuid( WPARAM wParam ) +{ + int idx = (wParam >> 16) & 0xFFFF; + return ( idx > 0 && idx <= lMuuids.getCount()) ? lMuuids[ idx-1 ] : NULL; +} + +int LangPackMarkPluginLoaded( PLUGININFOEX* pInfo ) +{ + LangPackMuuid tmp; tmp.muuid = pInfo->uuid; + int idx = lMuuids.getIndex( &tmp ); + if ( idx == -1 ) + return 0; + + lMuuids[ idx ]->pInfo = pInfo; + return (idx+1) << 16; +} + +void LangPackDropUnusedItems( void ) +{ + if ( langPack.entryCount == 0 ) + return; + + LangPackEntry *s = langPack.entry+1, *d = s, *pLast = langPack.entry; + DWORD dwSavedHash = langPack.entry->englishHash; + bool bSortNeeded = false; + + for ( int i=1; i < langPack.entryCount; i++, s++ ) { + if ( s->pMuuid != NULL && s->pMuuid->pInfo == NULL ) + s->pMuuid = NULL; + + if ( s->englishHash != dwSavedHash ) { + pLast = d; + if ( s != d ) + *d++ = *s; + else + d++; + dwSavedHash = s->englishHash; + } + else { + bSortNeeded = true; + LangPackEntry* p = ( LangPackEntry* )mir_alloc( sizeof( LangPackEntry )); + *p = *s; + pLast->pNext = p; pLast = p; + } + } + + if ( bSortNeeded ) { + langPack.entryCount = ( int )( d - langPack.entry ); + qsort(langPack.entry,langPack.entryCount,sizeof(LangPackEntry),(int(*)(const void*,const void*))SortLangPackHashesProc); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int LoadLangPackModule(void) +{ + HANDLE hFind; + TCHAR szSearch[MAX_PATH]; + WIN32_FIND_DATA fd; + + bModuleInitialized = TRUE; + + ZeroMemory(&langPack,sizeof(langPack)); + LoadLangPackServices(); + pathToAbsoluteT(_T("langpack_*.txt"), szSearch, NULL); + hFind = FindFirstFile( szSearch, &fd ); + if( hFind != INVALID_HANDLE_VALUE ) { + pathToAbsoluteT(fd.cFileName, szSearch, NULL); + FindClose(hFind); + LoadLangPack(szSearch); + } + return 0; +} + +void UnloadLangPackModule() +{ + int i; + + if ( !bModuleInitialized ) return; + + for ( i=0; i < lMuuids.getCount(); i++ ) + mir_free( lMuuids[i] ); + lMuuids.destroy(); + + LangPackEntry* p = langPack.entry; + for ( i=0; i < langPack.entryCount; i++, p++ ) { + if ( p->pNext != NULL ) { + for ( LangPackEntry* p1 = p->pNext; p1 != NULL; ) { + LangPackEntry* p2 = p1; p1 = p1->pNext; + mir_free( p2->local); + mir_free( p2->wlocal); + mir_free( p2 ); + } + } + + mir_free( p->local ); + mir_free( p->wlocal ); + } + + if ( langPack.entryCount ) { + mir_free(langPack.entry); + langPack.entry=0; + langPack.entryCount=0; +} } diff --git a/src/modules/langpack/lpservices.cpp b/src/modules/langpack/lpservices.cpp new file mode 100644 index 0000000000..26586dfda3 --- /dev/null +++ b/src/modules/langpack/lpservices.cpp @@ -0,0 +1,168 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "commonheaders.h" + +#if defined( _UNICODE ) + #define FLAGS LANG_UNICODE +#else + #define FLAGS 0 +#endif + +LangPackMuuid* __fastcall LangPackLookupUuid( WPARAM ); +int LangPackMarkPluginLoaded( PLUGININFOEX* pInfo ); + +///////////////////////////////////////////////////////////////////////////////////////// + +static INT_PTR TranslateString(WPARAM wParam,LPARAM lParam) +{ + return (INT_PTR)LangPackTranslateString( LangPackLookupUuid(wParam), (const char *)lParam, (wParam & LANG_UNICODE) ? 1 : 0); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static INT_PTR TranslateMenu(WPARAM wParam, LPARAM lParam) +{ + HMENU hMenu = ( HMENU )wParam; + int i; + MENUITEMINFO mii; + TCHAR str[256]; + LangPackMuuid* uuid = LangPackLookupUuid( lParam ); + + mii.cbSize = MENUITEMINFO_V4_SIZE; + for ( i = GetMenuItemCount( hMenu )-1; i >= 0; i--) { + mii.fMask = MIIM_TYPE|MIIM_SUBMENU; + mii.dwTypeData = ( TCHAR* )str; + mii.cch = SIZEOF(str); + GetMenuItemInfo(hMenu, i, TRUE, &mii); + + if ( mii.cch && mii.dwTypeData ) { + TCHAR* result = ( TCHAR* )LangPackTranslateString( uuid, ( const char* )mii.dwTypeData, FLAGS ); + if ( result != mii.dwTypeData ) { + mii.dwTypeData = result; + mii.fMask = MIIM_TYPE; + SetMenuItemInfo( hMenu, i, TRUE, &mii ); + } } + + if ( mii.hSubMenu != NULL ) TranslateMenu(( WPARAM )mii.hSubMenu, lParam ); + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static void TranslateWindow( LangPackMuuid* pUuid, HWND hwnd ) +{ + TCHAR title[2048]; + GetWindowText(hwnd, title, SIZEOF( title )); + { + TCHAR* result = ( TCHAR* )LangPackTranslateString( pUuid, ( const char* )title, FLAGS ); + if ( result != title ) + SetWindowText(hwnd, result ); +} } + +static BOOL CALLBACK TranslateDialogEnumProc(HWND hwnd,LPARAM lParam) +{ + LANGPACKTRANSLATEDIALOG *lptd = (LANGPACKTRANSLATEDIALOG*)lParam; + TCHAR szClass[32]; + int i,id = GetDlgCtrlID( hwnd ); + + if ( lptd->ignoreControls != NULL ) + for ( i=0; lptd->ignoreControls[i]; i++ ) + if ( lptd->ignoreControls[i] == id ) + return TRUE; + + LangPackMuuid* uuid = LangPackLookupUuid( lptd->flags ); + + GetClassName( hwnd, szClass, SIZEOF(szClass)); + if(!lstrcmpi(szClass,_T("static")) || !lstrcmpi(szClass,_T("hyperlink")) || !lstrcmpi(szClass,_T("button")) || !lstrcmpi(szClass,_T("MButtonClass")) || !lstrcmpi(szClass,_T("MHeaderbarCtrl"))) + TranslateWindow( uuid, hwnd ); + else if ( !lstrcmpi( szClass,_T("edit"))) { + if( lptd->flags & LPTDF_NOIGNOREEDIT || GetWindowLongPtr(hwnd,GWL_STYLE) & ES_READONLY ) + TranslateWindow( uuid, hwnd ); + } + return TRUE; +} + +static INT_PTR TranslateDialog(WPARAM wParam, LPARAM lParam) +{ + LANGPACKTRANSLATEDIALOG *lptd = (LANGPACKTRANSLATEDIALOG*)lParam; + if ( lptd == NULL || lptd->cbSize != sizeof(LANGPACKTRANSLATEDIALOG)) + return 1; + + if ( !( lptd->flags & LPTDF_NOTITLE )) + TranslateWindow( LangPackLookupUuid( lptd->flags ), lptd->hwndDlg ); + + EnumChildWindows( lptd->hwndDlg, TranslateDialogEnumProc, lParam ); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static INT_PTR LPRegister(WPARAM wParam, LPARAM lParam) +{ + *( int* )wParam = LangPackMarkPluginLoaded(( PLUGININFOEX* )lParam ); + return 0; +} + +static INT_PTR GetDefaultCodePage(WPARAM,LPARAM) +{ + return LangPackGetDefaultCodePage(); +} + +static INT_PTR GetDefaultLocale(WPARAM, LPARAM) +{ + return LangPackGetDefaultLocale(); +} + +static INT_PTR PcharToTchar(WPARAM wParam, LPARAM lParam) +{ + char* pszStr = ( char* )lParam; + if ( pszStr == NULL ) + return NULL; + + LangPackMuuid* uuid = LangPackLookupUuid( wParam ); + + #if defined( _UNICODE ) + { int len = (int)strlen( pszStr ); + TCHAR* result = ( TCHAR* )alloca(( len+1 )*sizeof( TCHAR )); + MultiByteToWideChar( LangPackGetDefaultCodePage(), 0, pszStr, -1, result, len ); + result[len] = 0; + return ( INT_PTR )mir_wstrdup(( wchar_t* )LangPackTranslateString( uuid, ( char* )result, 1 )); + } + #else + return ( INT_PTR )mir_strdup( LangPackTranslateString( uuid, pszStr, 0 )); + #endif +} + +int LoadLangPackServices(void) +{ + CreateServiceFunction(MS_LANGPACK_TRANSLATESTRING,TranslateString); + CreateServiceFunction(MS_LANGPACK_TRANSLATEMENU,TranslateMenu); + CreateServiceFunction(MS_LANGPACK_TRANSLATEDIALOG,TranslateDialog); + CreateServiceFunction(MS_LANGPACK_GETCODEPAGE,GetDefaultCodePage); + CreateServiceFunction(MS_LANGPACK_GETLOCALE,GetDefaultLocale); + CreateServiceFunction(MS_LANGPACK_PCHARTOTCHAR,PcharToTchar); + CreateServiceFunction(MS_LANGPACK_REGISTER,LPRegister); + return 0; +} + -- cgit v1.2.3