mirror of
https://github.com/reactos/wine.git
synced 2024-11-26 05:00:30 +00:00
abc0f385a3
The source is largely irrelevant since we are not likely to be wanting to ship updates to the MIME database as registry updates, instead of just changing the code.
2349 lines
69 KiB
C
2349 lines
69 KiB
C
/*
|
|
* MLANG Class Factory
|
|
*
|
|
* Copyright 2002 Lionel Ulmer
|
|
* Copyright 2003,2004 Mike McCormack
|
|
* Copyright 2004,2005 Dmitry Timoshkov
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#define COBJMACROS
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#include "winuser.h"
|
|
#include "winreg.h"
|
|
#include "ole2.h"
|
|
#include "mlang.h"
|
|
|
|
#include "uuids.h"
|
|
|
|
#include "wine/unicode.h"
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(mlang);
|
|
|
|
#include "initguid.h"
|
|
|
|
#define CP_UNICODE 1200
|
|
|
|
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
|
|
|
static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj);
|
|
|
|
static DWORD MLANG_tls_index; /* to store various per thead data */
|
|
|
|
/* FIXME:
|
|
* Under what circumstances HKEY_CLASSES_ROOT\MIME\Database\Codepage and
|
|
* HKEY_CLASSES_ROOT\MIME\Database\Charset are used?
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
const char *description;
|
|
UINT cp;
|
|
DWORD flags;
|
|
const char *web_charset;
|
|
const char *header_charset;
|
|
const char *body_charset;
|
|
} MIME_CP_INFO;
|
|
|
|
/* These data are based on the codepage info in libs/unicode/cpmap.pl */
|
|
/* FIXME: Add 28604 (Celtic), 28606 (Balkan) */
|
|
|
|
static const MIME_CP_INFO arabic_cp[] =
|
|
{
|
|
{ "Arabic (864)",
|
|
864, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"ibm864", "ibm864", "ibm864" },
|
|
{ "Arabic (1006)",
|
|
1006, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"ibm1006", "ibm1006", "ibm1006" },
|
|
{ "Arabic (Windows)",
|
|
1256, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1256", "windows-1256", "windows-1256" },
|
|
{ "Arabic (ISO)",
|
|
28596, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-6", "iso-8859-6", "iso-8859-6" }
|
|
};
|
|
static const MIME_CP_INFO baltic_cp[] =
|
|
{
|
|
{ "Baltic (DOS)",
|
|
775, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm775", "ibm775", "ibm775" },
|
|
{ "Baltic (Windows)",
|
|
1257, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1257", "windows-1257", "windows-1257" },
|
|
{ "Baltic (ISO)",
|
|
28594, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"iso-8859-4", "iso-8859-4", "iso-8859-4" },
|
|
{ "Estonian (ISO)",
|
|
28603, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-13", "iso-8859-13", "iso-8859-13" }
|
|
};
|
|
static const MIME_CP_INFO chinese_simplified_cp[] =
|
|
{
|
|
{ "Chinese Simplified (GB2312)",
|
|
936, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"gb2312", "gb2312", "gb2312" }
|
|
};
|
|
static const MIME_CP_INFO chinese_traditional_cp[] =
|
|
{
|
|
{ "Chinese Traditional (Big5)",
|
|
950, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"big5", "big5", "big5" }
|
|
};
|
|
static const MIME_CP_INFO central_european_cp[] =
|
|
{
|
|
{ "Central European (DOS)",
|
|
852, MIMECONTF_BROWSER | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"ibm852", "ibm852", "ibm852" },
|
|
{ "Central European (Windows)",
|
|
1250, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"windows-1250", "windows-1250", "windows-1250" },
|
|
{ "Central European (Mac)",
|
|
10029, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"x-mac-ce", "x-mac-ce", "x-mac-ce" },
|
|
{ "Central European (ISO)",
|
|
28592, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-2", "iso-8859-2", "iso-8859-2" }
|
|
};
|
|
static const MIME_CP_INFO cyrillic_cp[] =
|
|
{
|
|
{ "OEM Cyrillic",
|
|
855, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm855", "ibm855", "ibm855" },
|
|
{ "Cyrillic (DOS)",
|
|
866, MIMECONTF_BROWSER | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
|
|
MIMECONTF_MIME_LATEST,
|
|
"cp866", "cp866", "cp866" },
|
|
#if 0 /* Windows has 20866 as an official code page for KOI8-R */
|
|
{ "Cyrillic (KOI8-R)",
|
|
878, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"koi8-r", "koi8-r", "koi8-r" },
|
|
#endif
|
|
{ "Cyrillic (Windows)",
|
|
1251, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1251", "windows-1251", "windows-1251" },
|
|
{ "Cyrillic (Mac)",
|
|
10007, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"x-mac-cyrillic", "x-mac-cyrillic", "x-mac-cyrillic" },
|
|
{ "Cyrillic (KOI8-R)",
|
|
20866, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"koi8-r", "koi8-r", "koi8-r" },
|
|
{ "Cyrillic (KOI8-U)",
|
|
21866, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"koi8-u", "koi8-u", "koi8-u" },
|
|
{ "Cyrillic (ISO)",
|
|
28595, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-5", "iso-8859-5", "iso-8859-5" }
|
|
};
|
|
static const MIME_CP_INFO greek_cp[] =
|
|
{
|
|
{ "Greek (DOS)",
|
|
737, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"ibm737", "ibm737", "ibm737" },
|
|
{ "Greek, Modern (DOS)",
|
|
869, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"ibm869", "ibm869", "ibm869" },
|
|
{ "IBM EBCDIC (Greek Modern)",
|
|
875, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"cp875", "cp875", "cp875" },
|
|
{ "Greek (Windows)",
|
|
1253, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1253", "windows-1253", "windows-1253" },
|
|
{ "Greek (Mac)",
|
|
10006, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"x-mac-greek", "x-mac-greek", "x-mac-greek" },
|
|
{ "Greek (ISO)",
|
|
28597, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-7", "iso-8859-7", "iso-8859-7" }
|
|
};
|
|
static const MIME_CP_INFO hebrew_cp[] =
|
|
{
|
|
{ "Hebrew (424)",
|
|
424, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"ibm424", "ibm424", "ibm424" },
|
|
{ "Hebrew (856)",
|
|
856, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"cp856", "cp856", "cp856" },
|
|
{ "Hebrew (DOS)",
|
|
862, MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"dos-862", "dos-862", "dos-862" },
|
|
{ "Hebrew (Windows)",
|
|
1255, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1255", "windows-1255", "windows-1255" },
|
|
{ "Hebrew (ISO-Visual)",
|
|
28598, MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-8", "iso-8859-8", "iso-8859-8" }
|
|
};
|
|
static const MIME_CP_INFO japanese_cp[] =
|
|
{
|
|
{ "Japanese (Shift-JIS)",
|
|
932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"shift_jis", "iso-2022-jp", "iso-2022-jp" },
|
|
{ "Japanese (JIS 0208-1990 and 0212-1990)",
|
|
20932, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"euc-jp", "euc-jp", "euc-jp" }
|
|
};
|
|
static const MIME_CP_INFO korean_cp[] =
|
|
{
|
|
{ "Korean",
|
|
949, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"ks_c_5601-1987", "ks_c_5601-1987", "ks_c_5601-1987" }
|
|
};
|
|
static const MIME_CP_INFO thai_cp[] =
|
|
{
|
|
{ "Thai (Windows)",
|
|
874, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_MIME_LATEST,
|
|
"ibm-thai", "ibm-thai", "ibm-thai" }
|
|
};
|
|
static const MIME_CP_INFO turkish_cp[] =
|
|
{
|
|
{ "Turkish (DOS)",
|
|
857, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm857", "ibm857", "ibm857" },
|
|
{ "IBM EBCDIC (Turkish Latin-5)",
|
|
1026, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm1026", "ibm1026", "ibm1026" },
|
|
{ "Turkish (Windows)",
|
|
1254, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1254", "windows-1254", "windows-1254" },
|
|
{ "Turkish (Mac)",
|
|
10081, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"x-mac-turkish", "x-mac-turkish", "x-mac-turkish" },
|
|
{ "Latin 3 (ISO)",
|
|
28593, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-3", "iso-8859-3", "iso-8859-3" },
|
|
{ "Turkish (ISO)",
|
|
28599, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"iso-8859-9", "iso-8859-9", "iso-8859-9" }
|
|
};
|
|
static const MIME_CP_INFO vietnamese_cp[] =
|
|
{
|
|
{ "Vietnamese (Windows)",
|
|
1258, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
|
|
MIMECONTF_MIME_LATEST,
|
|
"windows-1258", "windows-1258", "windows-1258" }
|
|
};
|
|
static const MIME_CP_INFO western_cp[] =
|
|
{
|
|
{ "IBM EBCDIC (US-Canada)",
|
|
37, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm037", "ibm037", "ibm037" },
|
|
{ "OEM United States",
|
|
437, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm437", "ibm437", "ibm437" },
|
|
{ "IBM EBCDIC (International)",
|
|
500, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm500", "ibm500", "ibm500" },
|
|
{ "Western European (DOS)",
|
|
850, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm850", "ibm850", "ibm850" },
|
|
{ "Portuguese (DOS)",
|
|
860, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm860", "ibm860", "ibm860" },
|
|
{ "Icelandic (DOS)",
|
|
861, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm861", "ibm861", "ibm861" },
|
|
{ "French Canadian (DOS)",
|
|
863, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm863", "ibm863", "ibm863" },
|
|
{ "Nordic (DOS)",
|
|
865, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"ibm865", "ibm865", "ibm865" },
|
|
{ "Western European (Windows)",
|
|
1252, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
|
|
MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"windows-1252", "windows-1252", "iso-8859-1" },
|
|
{ "Western European (Mac)",
|
|
10000, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"macintosh", "macintosh", "macintosh" },
|
|
{ "Icelandic (Mac)",
|
|
10079, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"x-mac-icelandic", "x-mac-icelandic", "x-mac-icelandic" },
|
|
{ "US-ASCII",
|
|
20127, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT | MIMECONTF_EXPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
|
|
"us-ascii", "us-ascii", "us-ascii" },
|
|
{ "Western European (ISO)",
|
|
28591, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"iso-8859-1", "iso-8859-1", "iso-8859-1" },
|
|
{ "Latin 9 (ISO)",
|
|
28605, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_LATEST,
|
|
"iso-8859-15", "iso-8859-15", "iso-8859-15" }
|
|
};
|
|
static const MIME_CP_INFO unicode_cp[] =
|
|
{
|
|
{ "Unicode",
|
|
CP_UNICODE, MIMECONTF_MINIMAL | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
|
|
MIMECONTF_VALID | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
|
|
MIMECONTF_MIME_LATEST,
|
|
"unicode", "unicode", "unicode" },
|
|
{ "Unicode (UTF-7)",
|
|
CP_UTF7, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_VALID |
|
|
MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"utf-7", "utf-7", "utf-7" },
|
|
{ "Unicode (UTF-8)",
|
|
CP_UTF8, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
|
|
MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
|
|
MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
|
|
MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
|
|
"utf-8", "utf-8", "utf-8" }
|
|
};
|
|
|
|
static const struct mlang_data
|
|
{
|
|
const char *description;
|
|
UINT family_codepage;
|
|
UINT number_of_cp;
|
|
const MIME_CP_INFO *mime_cp_info;
|
|
const char *fixed_font;
|
|
const char *proportional_font;
|
|
} mlang_data[] =
|
|
{
|
|
{ "Arabic",1256,sizeof(arabic_cp)/sizeof(arabic_cp[0]),arabic_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Baltic",1257,sizeof(baltic_cp)/sizeof(baltic_cp[0]),baltic_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Chinese Simplified",936,sizeof(chinese_simplified_cp)/sizeof(chinese_simplified_cp[0]),chinese_simplified_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Chinese Traditional",950,sizeof(chinese_traditional_cp)/sizeof(chinese_traditional_cp[0]),chinese_traditional_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Central European",1250,sizeof(central_european_cp)/sizeof(central_european_cp[0]),central_european_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Cyrillic",1251,sizeof(cyrillic_cp)/sizeof(cyrillic_cp[0]),cyrillic_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Greek",1253,sizeof(greek_cp)/sizeof(greek_cp[0]),greek_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Hebrew",1255,sizeof(hebrew_cp)/sizeof(hebrew_cp[0]),hebrew_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Japanese",932,sizeof(japanese_cp)/sizeof(japanese_cp[0]),japanese_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Korean",949,sizeof(korean_cp)/sizeof(korean_cp[0]),korean_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Thai",874,sizeof(thai_cp)/sizeof(thai_cp[0]),thai_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Turkish",1254,sizeof(turkish_cp)/sizeof(turkish_cp[0]),turkish_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Vietnamese",1258,sizeof(vietnamese_cp)/sizeof(vietnamese_cp[0]),vietnamese_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Western European",1252,sizeof(western_cp)/sizeof(western_cp[0]),western_cp,
|
|
"Courier","Arial" }, /* FIXME */
|
|
{ "Unicode",CP_UNICODE,sizeof(unicode_cp)/sizeof(unicode_cp[0]),unicode_cp,
|
|
"Courier","Arial" } /* FIXME */
|
|
};
|
|
|
|
static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info);
|
|
|
|
static LONG dll_count;
|
|
|
|
/*
|
|
* Dll lifetime tracking declaration
|
|
*/
|
|
static void LockModule(void)
|
|
{
|
|
InterlockedIncrement(&dll_count);
|
|
}
|
|
|
|
static void UnlockModule(void)
|
|
{
|
|
InterlockedDecrement(&dll_count);
|
|
}
|
|
|
|
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|
{
|
|
switch(fdwReason) {
|
|
case DLL_PROCESS_ATTACH:
|
|
MLANG_tls_index = TlsAlloc();
|
|
DisableThreadLibraryCalls(hInstDLL);
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
TlsFree(MLANG_tls_index);
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
HRESULT WINAPI ConvertINetMultiByteToUnicode(
|
|
LPDWORD pdwMode,
|
|
DWORD dwEncoding,
|
|
LPCSTR pSrcStr,
|
|
LPINT pcSrcSize,
|
|
LPWSTR pDstStr,
|
|
LPINT pcDstSize)
|
|
{
|
|
INT src_len = -1;
|
|
|
|
TRACE("%p %ld %s %p %p %p\n", pdwMode, dwEncoding,
|
|
debugstr_a(pSrcStr), pcSrcSize, pDstStr, pcDstSize);
|
|
|
|
if (!pcDstSize)
|
|
return E_FAIL;
|
|
|
|
if (!pcSrcSize)
|
|
pcSrcSize = &src_len;
|
|
|
|
if (!*pcSrcSize)
|
|
{
|
|
*pcDstSize = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
switch (dwEncoding)
|
|
{
|
|
case CP_UNICODE:
|
|
if (*pcSrcSize == -1)
|
|
*pcSrcSize = lstrlenW((LPCWSTR)pSrcStr);
|
|
*pcDstSize = min(*pcSrcSize, *pcDstSize);
|
|
*pcSrcSize *= sizeof(WCHAR);
|
|
if (pDstStr)
|
|
memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR));
|
|
break;
|
|
|
|
default:
|
|
if (*pcSrcSize == -1)
|
|
*pcSrcSize = lstrlenA(pSrcStr);
|
|
|
|
if (pDstStr)
|
|
*pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize);
|
|
else
|
|
*pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0);
|
|
break;
|
|
}
|
|
|
|
if (!*pcDstSize)
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI ConvertINetUnicodeToMultiByte(
|
|
LPDWORD pdwMode,
|
|
DWORD dwEncoding,
|
|
LPCWSTR pSrcStr,
|
|
LPINT pcSrcSize,
|
|
LPSTR pDstStr,
|
|
LPINT pcDstSize)
|
|
{
|
|
|
|
INT src_len = -1;
|
|
|
|
TRACE("%p %ld %s %p %p %p\n", pdwMode, dwEncoding,
|
|
debugstr_w(pSrcStr), pcSrcSize, pDstStr, pcDstSize);
|
|
|
|
if (!pcDstSize)
|
|
return E_FAIL;
|
|
|
|
if (!pcSrcSize)
|
|
pcSrcSize = &src_len;
|
|
|
|
if (!*pcSrcSize)
|
|
{
|
|
*pcDstSize = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
switch (dwEncoding)
|
|
{
|
|
case CP_UNICODE:
|
|
if (*pcSrcSize == -1)
|
|
*pcSrcSize = lstrlenW(pSrcStr);
|
|
*pcDstSize = min(*pcSrcSize * sizeof(WCHAR), *pcDstSize);
|
|
if (pDstStr)
|
|
memmove(pDstStr, pSrcStr, *pcDstSize);
|
|
break;
|
|
|
|
default:
|
|
if (*pcSrcSize == -1)
|
|
*pcSrcSize = lstrlenW(pSrcStr);
|
|
|
|
if (pDstStr)
|
|
*pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize, NULL, NULL);
|
|
else
|
|
*pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0, NULL, NULL);
|
|
break;
|
|
}
|
|
|
|
|
|
if (!*pcDstSize)
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT WINAPI ConvertINetString(
|
|
LPDWORD pdwMode,
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding,
|
|
LPCSTR pSrcStr,
|
|
LPINT pcSrcSize,
|
|
LPSTR pDstStr,
|
|
LPINT pcDstSize
|
|
)
|
|
{
|
|
FIXME("%p %ld %ld %s %p %p %p: stub!\n", pdwMode, dwSrcEncoding, dwDstEncoding,
|
|
debugstr_a(pSrcStr), pcSrcSize, pDstStr, pcDstSize);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT GetFamilyCodePage(
|
|
UINT uiCodePage,
|
|
UINT* puiFamilyCodePage)
|
|
{
|
|
UINT i, n;
|
|
|
|
TRACE("%u %p\n", uiCodePage, puiFamilyCodePage);
|
|
|
|
if (!puiFamilyCodePage) return S_FALSE;
|
|
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
{
|
|
for (n = 0; n < mlang_data[i].number_of_cp; n++)
|
|
{
|
|
if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
|
|
{
|
|
*puiFamilyCodePage = mlang_data[i].family_codepage;
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT WINAPI IsConvertINetStringAvailable(
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding)
|
|
{
|
|
UINT src_family, dst_family;
|
|
|
|
TRACE("%ld %ld\n", dwSrcEncoding, dwDstEncoding);
|
|
|
|
if (GetFamilyCodePage(dwSrcEncoding, &src_family) != S_OK ||
|
|
GetFamilyCodePage(dwDstEncoding, &dst_family) != S_OK)
|
|
return S_FALSE;
|
|
|
|
if (src_family == dst_family) return S_OK;
|
|
|
|
/* we can convert any codepage to/from unicode */
|
|
if (src_family == CP_UNICODE || dst_family == CP_UNICODE) return S_OK;
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT WINAPI LcidToRfc1766A(
|
|
LCID Locale,
|
|
LPSTR pszRfc1766,
|
|
INT nChar)
|
|
{
|
|
FIXME("%ld %s %u\n", Locale, pszRfc1766, nChar);
|
|
return S_FALSE;
|
|
}
|
|
|
|
HRESULT WINAPI LcidToRfc1766W(
|
|
LCID Locale,
|
|
LPWSTR pszRfc1766,
|
|
INT nChar)
|
|
{
|
|
FIXME("%ld %p %u\n", Locale, pszRfc1766, nChar);
|
|
return S_FALSE;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* MLANG ClassFactory
|
|
*/
|
|
typedef struct {
|
|
IClassFactory ITF_IClassFactory;
|
|
|
|
LONG ref;
|
|
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
|
} IClassFactoryImpl;
|
|
|
|
struct object_creation_info
|
|
{
|
|
const CLSID *clsid;
|
|
LPCSTR szClassName;
|
|
HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
|
|
};
|
|
|
|
static const struct object_creation_info object_creation[] =
|
|
{
|
|
{ &CLSID_CMultiLanguage, "CLSID_CMultiLanguage", MultiLanguage_create },
|
|
};
|
|
|
|
static HRESULT WINAPI
|
|
MLANGCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
|
|
{
|
|
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
|
|
|
TRACE("%s\n", debugstr_guid(riid) );
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IClassFactory))
|
|
{
|
|
IClassFactory_AddRef(iface);
|
|
*ppobj = This;
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI MLANGCF_AddRef(LPCLASSFACTORY iface)
|
|
{
|
|
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI MLANGCF_Release(LPCLASSFACTORY iface)
|
|
{
|
|
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
|
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
if (ref == 0)
|
|
{
|
|
TRACE("Destroying %p\n", This);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI MLANGCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter,
|
|
REFIID riid, LPVOID *ppobj)
|
|
{
|
|
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
|
HRESULT hres;
|
|
LPUNKNOWN punk;
|
|
|
|
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
|
|
|
|
*ppobj = NULL;
|
|
hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
|
|
if (SUCCEEDED(hres)) {
|
|
hres = IUnknown_QueryInterface(punk, riid, ppobj);
|
|
IUnknown_Release(punk);
|
|
}
|
|
TRACE("returning (%p) -> %lx\n", *ppobj, hres);
|
|
return hres;
|
|
}
|
|
|
|
static HRESULT WINAPI MLANGCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)
|
|
{
|
|
if (dolock)
|
|
LockModule();
|
|
else
|
|
UnlockModule();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static const IClassFactoryVtbl MLANGCF_Vtbl =
|
|
{
|
|
MLANGCF_QueryInterface,
|
|
MLANGCF_AddRef,
|
|
MLANGCF_Release,
|
|
MLANGCF_CreateInstance,
|
|
MLANGCF_LockServer
|
|
};
|
|
|
|
/******************************************************************
|
|
* DllGetClassObject (MLANG.@)
|
|
*/
|
|
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
|
{
|
|
int i;
|
|
IClassFactoryImpl *factory;
|
|
|
|
TRACE("%s %s %p\n",debugstr_guid(rclsid), debugstr_guid(iid), ppv);
|
|
|
|
if ( !IsEqualGUID( &IID_IClassFactory, iid )
|
|
&& ! IsEqualGUID( &IID_IUnknown, iid) )
|
|
return E_NOINTERFACE;
|
|
|
|
for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
|
|
{
|
|
if (IsEqualGUID(object_creation[i].clsid, rclsid))
|
|
break;
|
|
}
|
|
|
|
if (i == sizeof(object_creation)/sizeof(object_creation[0]))
|
|
{
|
|
FIXME("%s: no class found.\n", debugstr_guid(rclsid));
|
|
return CLASS_E_CLASSNOTAVAILABLE;
|
|
}
|
|
|
|
TRACE("Creating a class factory for %s\n",object_creation[i].szClassName);
|
|
|
|
factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
|
|
if (factory == NULL) return E_OUTOFMEMORY;
|
|
|
|
factory->ITF_IClassFactory.lpVtbl = &MLANGCF_Vtbl;
|
|
factory->ref = 1;
|
|
|
|
factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
|
|
|
|
*ppv = &(factory->ITF_IClassFactory);
|
|
|
|
TRACE("(%p) <- %p\n", ppv, &(factory->ITF_IClassFactory) );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
typedef struct tagMLang_impl
|
|
{
|
|
const IMLangFontLinkVtbl *vtbl_IMLangFontLink;
|
|
const IMultiLanguageVtbl *vtbl_IMultiLanguage;
|
|
const IMultiLanguage2Vtbl *vtbl_IMultiLanguage2;
|
|
LONG ref;
|
|
DWORD total_cp, total_scripts;
|
|
} MLang_impl;
|
|
|
|
static ULONG WINAPI MLang_AddRef( MLang_impl* This)
|
|
{
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI MLang_Release( MLang_impl* This )
|
|
{
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("%p ref = %ld\n", This, ref);
|
|
if (ref == 0)
|
|
{
|
|
TRACE("Destroying %p\n", This);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
UnlockModule();
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI MLang_QueryInterface(
|
|
MLang_impl* This,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
TRACE("%p -> %s\n", This, debugstr_guid(riid) );
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IMLangCodePages)
|
|
|| IsEqualGUID(riid, &IID_IMLangFontLink))
|
|
{
|
|
MLang_AddRef(This);
|
|
TRACE("Returning IID_IMLangFontLink %p ref = %ld\n", This, This->ref);
|
|
*ppvObject = &(This->vtbl_IMLangFontLink);
|
|
return S_OK;
|
|
}
|
|
|
|
if (IsEqualGUID(riid, &IID_IMultiLanguage) )
|
|
{
|
|
MLang_AddRef(This);
|
|
TRACE("Returning IID_IMultiLanguage %p ref = %ld\n", This, This->ref);
|
|
*ppvObject = &(This->vtbl_IMultiLanguage);
|
|
return S_OK;
|
|
}
|
|
|
|
if (IsEqualGUID(riid, &IID_IMultiLanguage2) )
|
|
{
|
|
MLang_AddRef(This);
|
|
*ppvObject = &(This->vtbl_IMultiLanguage2);
|
|
TRACE("Returning IID_IMultiLanguage2 %p ref = %ld\n", This, This->ref);
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
typedef struct tagEnumCodePage_impl
|
|
{
|
|
const IEnumCodePageVtbl *vtbl_IEnumCodePage;
|
|
LONG ref;
|
|
MIMECPINFO *cpinfo;
|
|
DWORD total, pos;
|
|
} EnumCodePage_impl;
|
|
|
|
static HRESULT WINAPI fnIEnumCodePage_QueryInterface(
|
|
IEnumCodePage* iface,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
|
|
TRACE("%p -> %s\n", This, debugstr_guid(riid) );
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IEnumCodePage))
|
|
{
|
|
IEnumCodePage_AddRef(iface);
|
|
TRACE("Returning IID_IEnumCodePage %p ref = %ld\n", This, This->ref);
|
|
*ppvObject = &(This->vtbl_IEnumCodePage);
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI fnIEnumCodePage_AddRef(
|
|
IEnumCodePage* iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI fnIEnumCodePage_Release(
|
|
IEnumCodePage* iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("%p ref = %ld\n", This, ref);
|
|
if (ref == 0)
|
|
{
|
|
TRACE("Destroying %p\n", This);
|
|
HeapFree(GetProcessHeap(), 0, This->cpinfo);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumCodePage_Clone(
|
|
IEnumCodePage* iface,
|
|
IEnumCodePage** ppEnum)
|
|
{
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
FIXME("%p %p\n", This, ppEnum);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumCodePage_Next(
|
|
IEnumCodePage* iface,
|
|
ULONG celt,
|
|
PMIMECPINFO rgelt,
|
|
ULONG* pceltFetched)
|
|
{
|
|
ULONG i;
|
|
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
TRACE("%p %lu %p %p\n", This, celt, rgelt, pceltFetched);
|
|
|
|
if (!pceltFetched) return S_FALSE;
|
|
*pceltFetched = 0;
|
|
|
|
if (!rgelt) return S_FALSE;
|
|
|
|
if (This->pos + celt > This->total)
|
|
celt = This->total - This->pos;
|
|
|
|
if (!celt) return S_FALSE;
|
|
|
|
memcpy(rgelt, This->cpinfo + This->pos, celt * sizeof(MIMECPINFO));
|
|
*pceltFetched = celt;
|
|
This->pos += celt;
|
|
|
|
for (i = 0; i < celt; i++)
|
|
{
|
|
TRACE("#%lu: %08lx %u %u %s %s %s %s %s %s %d\n",
|
|
i, rgelt[i].dwFlags, rgelt[i].uiCodePage,
|
|
rgelt[i].uiFamilyCodePage,
|
|
wine_dbgstr_w(rgelt[i].wszDescription),
|
|
wine_dbgstr_w(rgelt[i].wszWebCharset),
|
|
wine_dbgstr_w(rgelt[i].wszHeaderCharset),
|
|
wine_dbgstr_w(rgelt[i].wszBodyCharset),
|
|
wine_dbgstr_w(rgelt[i].wszFixedWidthFont),
|
|
wine_dbgstr_w(rgelt[i].wszProportionalFont),
|
|
rgelt[i].bGDICharset);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumCodePage_Reset(
|
|
IEnumCodePage* iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
TRACE("%p\n", This);
|
|
|
|
This->pos = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumCodePage_Skip(
|
|
IEnumCodePage* iface,
|
|
ULONG celt)
|
|
{
|
|
ICOM_THIS_MULTI(EnumCodePage_impl, vtbl_IEnumCodePage, iface);
|
|
TRACE("%p %lu\n", This, celt);
|
|
|
|
if (celt >= This->total) return S_FALSE;
|
|
|
|
This->pos += celt;
|
|
return S_OK;
|
|
}
|
|
|
|
static const IEnumCodePageVtbl IEnumCodePage_vtbl =
|
|
{
|
|
fnIEnumCodePage_QueryInterface,
|
|
fnIEnumCodePage_AddRef,
|
|
fnIEnumCodePage_Release,
|
|
fnIEnumCodePage_Clone,
|
|
fnIEnumCodePage_Next,
|
|
fnIEnumCodePage_Reset,
|
|
fnIEnumCodePage_Skip
|
|
};
|
|
|
|
static HRESULT EnumCodePage_create( MLang_impl* mlang, DWORD grfFlags,
|
|
LANGID LangId, IEnumCodePage** ppEnumCodePage )
|
|
{
|
|
EnumCodePage_impl *ecp;
|
|
MIMECPINFO *cpinfo;
|
|
UINT i, n;
|
|
|
|
TRACE("%p, %08lx, %04x, %p\n", mlang, grfFlags, LangId, ppEnumCodePage);
|
|
|
|
if (!grfFlags) /* enumerate internal data base of encodings */
|
|
grfFlags = MIMECONTF_MIME_LATEST;
|
|
|
|
ecp = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumCodePage_impl) );
|
|
ecp->vtbl_IEnumCodePage = &IEnumCodePage_vtbl;
|
|
ecp->ref = 1;
|
|
ecp->pos = 0;
|
|
ecp->total = 0;
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
{
|
|
for (n = 0; n < mlang_data[i].number_of_cp; n++)
|
|
{
|
|
if (mlang_data[i].mime_cp_info[n].flags & grfFlags)
|
|
ecp->total++;
|
|
}
|
|
}
|
|
|
|
ecp->cpinfo = HeapAlloc(GetProcessHeap(), 0,
|
|
sizeof(MIMECPINFO) * ecp->total);
|
|
cpinfo = ecp->cpinfo;
|
|
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
{
|
|
for (n = 0; n < mlang_data[i].number_of_cp; n++)
|
|
{
|
|
if (mlang_data[i].mime_cp_info[n].flags & grfFlags)
|
|
fill_cp_info(&mlang_data[i], n, cpinfo++);
|
|
}
|
|
}
|
|
|
|
TRACE("enumerated %ld codepages with flags %08lx\n", ecp->total, grfFlags);
|
|
|
|
*ppEnumCodePage = (IEnumCodePage*) ecp;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
typedef struct tagEnumScript_impl
|
|
{
|
|
const IEnumScriptVtbl *vtbl_IEnumScript;
|
|
LONG ref;
|
|
SCRIPTINFO *script_info;
|
|
DWORD total, pos;
|
|
} EnumScript_impl;
|
|
|
|
static HRESULT WINAPI fnIEnumScript_QueryInterface(
|
|
IEnumScript* iface,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
|
|
TRACE("%p -> %s\n", This, debugstr_guid(riid) );
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IEnumScript))
|
|
{
|
|
IEnumScript_AddRef(iface);
|
|
TRACE("Returning IID_IEnumScript %p ref = %ld\n", This, This->ref);
|
|
*ppvObject = &(This->vtbl_IEnumScript);
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI fnIEnumScript_AddRef(
|
|
IEnumScript* iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI fnIEnumScript_Release(
|
|
IEnumScript* iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("%p ref = %ld\n", This, ref);
|
|
if (ref == 0)
|
|
{
|
|
TRACE("Destroying %p\n", This);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumScript_Clone(
|
|
IEnumScript* iface,
|
|
IEnumScript** ppEnum)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
FIXME("%p %p: stub!\n", This, ppEnum);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumScript_Next(
|
|
IEnumScript* iface,
|
|
ULONG celt,
|
|
PSCRIPTINFO rgelt,
|
|
ULONG* pceltFetched)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
TRACE("%p %lu %p %p\n", This, celt, rgelt, pceltFetched);
|
|
|
|
if (!pceltFetched || !rgelt) return E_FAIL;
|
|
|
|
*pceltFetched = 0;
|
|
|
|
if (This->pos + celt > This->total)
|
|
celt = This->total - This->pos;
|
|
|
|
if (!celt) return S_FALSE;
|
|
|
|
memcpy(rgelt, This->script_info + This->pos, celt * sizeof(SCRIPTINFO));
|
|
*pceltFetched = celt;
|
|
This->pos += celt;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumScript_Reset(
|
|
IEnumScript* iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
TRACE("%p\n", This);
|
|
|
|
This->pos = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumScript_Skip(
|
|
IEnumScript* iface,
|
|
ULONG celt)
|
|
{
|
|
ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
|
|
TRACE("%p %lu\n", This, celt);
|
|
|
|
if (celt >= This->total) return S_FALSE;
|
|
|
|
This->pos += celt;
|
|
return S_OK;
|
|
}
|
|
|
|
static const IEnumScriptVtbl IEnumScript_vtbl =
|
|
{
|
|
fnIEnumScript_QueryInterface,
|
|
fnIEnumScript_AddRef,
|
|
fnIEnumScript_Release,
|
|
fnIEnumScript_Clone,
|
|
fnIEnumScript_Next,
|
|
fnIEnumScript_Reset,
|
|
fnIEnumScript_Skip
|
|
};
|
|
|
|
static HRESULT EnumScript_create( MLang_impl* mlang, DWORD dwFlags,
|
|
LANGID LangId, IEnumScript** ppEnumScript )
|
|
{
|
|
EnumScript_impl *es;
|
|
UINT i;
|
|
|
|
TRACE("%p, %08lx, %04x, %p: stub!\n", mlang, dwFlags, LangId, ppEnumScript);
|
|
|
|
if (!dwFlags) /* enumerate all available scripts */
|
|
dwFlags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM;
|
|
|
|
es = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumScript_impl) );
|
|
es->vtbl_IEnumScript = &IEnumScript_vtbl;
|
|
es->ref = 1;
|
|
es->pos = 0;
|
|
/* do not enumerate unicode flavours */
|
|
es->total = sizeof(mlang_data)/sizeof(mlang_data[0]) - 1;
|
|
es->script_info = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPTINFO) * es->total);
|
|
|
|
for (i = 0; i < es->total; i++)
|
|
{
|
|
es->script_info[i].ScriptId = i;
|
|
es->script_info[i].uiCodePage = mlang_data[i].family_codepage;
|
|
MultiByteToWideChar(CP_ACP, 0, mlang_data[i].description, -1,
|
|
es->script_info[i].wszDescription, MAX_SCRIPT_NAME);
|
|
MultiByteToWideChar(CP_ACP, 0, mlang_data[i].fixed_font, -1,
|
|
es->script_info[i].wszFixedWidthFont, MAX_MIMEFACE_NAME);
|
|
MultiByteToWideChar(CP_ACP, 0, mlang_data[i].proportional_font, -1,
|
|
es->script_info[i].wszProportionalFont, MAX_MIMEFACE_NAME);
|
|
}
|
|
|
|
TRACE("enumerated %ld scripts with flags %08lx\n", es->total, dwFlags);
|
|
|
|
*ppEnumScript = (IEnumScript *)es;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_QueryInterface(
|
|
IMLangFontLink* iface,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangFontLink, iface);
|
|
return MLang_QueryInterface( This, riid, ppvObject );
|
|
}
|
|
|
|
static ULONG WINAPI fnIMLangFontLink_AddRef(
|
|
IMLangFontLink* iface)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangFontLink, iface);
|
|
return MLang_AddRef( This );
|
|
}
|
|
|
|
static ULONG WINAPI fnIMLangFontLink_Release(
|
|
IMLangFontLink* iface)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangFontLink, iface);
|
|
return MLang_Release( This );
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_GetCharCodePages(
|
|
IMLangFontLink* iface,
|
|
WCHAR chSrc,
|
|
DWORD* pdwCodePages)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_GetStrCodePages(
|
|
IMLangFontLink* iface,
|
|
const WCHAR* pszSrc,
|
|
long cchSrc,
|
|
DWORD dwPriorityCodePages,
|
|
DWORD* pdwCodePages,
|
|
long* pcchCodePages)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_CodePageToCodePages(
|
|
IMLangFontLink* iface,
|
|
UINT uCodePage,
|
|
DWORD* pdwCodePages)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangFontLink, iface);
|
|
CHARSETINFO cs;
|
|
BOOL rc;
|
|
|
|
TRACE("(%p) Seeking %u\n",This, uCodePage);
|
|
memset(&cs, 0, sizeof(cs));
|
|
|
|
rc = TranslateCharsetInfo((DWORD*)uCodePage, &cs, TCI_SRCCODEPAGE);
|
|
|
|
if (rc)
|
|
{
|
|
*pdwCodePages = cs.fs.fsCsb[0];
|
|
TRACE("resulting CodePages 0x%lx\n",*pdwCodePages);
|
|
}
|
|
else
|
|
TRACE("CodePage Not Found\n");
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_CodePagesToCodePage(
|
|
IMLangFontLink* iface,
|
|
DWORD dwCodePages,
|
|
UINT uDefaultCodePage,
|
|
UINT* puCodePage)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangFontLink, iface);
|
|
DWORD mask = 0x00000000;
|
|
UINT i;
|
|
CHARSETINFO cs;
|
|
BOOL rc;
|
|
|
|
TRACE("(%p) scanning 0x%lx default page %u\n",This, dwCodePages,
|
|
uDefaultCodePage);
|
|
|
|
*puCodePage = 0x00000000;
|
|
|
|
rc = TranslateCharsetInfo((DWORD*)uDefaultCodePage, &cs, TCI_SRCCODEPAGE);
|
|
|
|
if (rc && (dwCodePages & cs.fs.fsCsb[0]))
|
|
{
|
|
TRACE("Found Default Codepage\n");
|
|
*puCodePage = uDefaultCodePage;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
|
|
mask = 1 << i;
|
|
if (dwCodePages & mask)
|
|
{
|
|
DWORD Csb[2];
|
|
Csb[0] = mask;
|
|
Csb[1] = 0x0;
|
|
rc = TranslateCharsetInfo((DWORD*)Csb, &cs, TCI_SRCFONTSIG);
|
|
if (!rc)
|
|
continue;
|
|
|
|
TRACE("Falling back to least significant found CodePage %u\n",
|
|
cs.ciACP);
|
|
*puCodePage = cs.ciACP;
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
TRACE("no codepage found\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_GetFontCodePages(
|
|
IMLangFontLink* iface,
|
|
HDC hDC,
|
|
HFONT hFont,
|
|
DWORD* pdwCodePages)
|
|
{
|
|
HFONT old_font;
|
|
FONTSIGNATURE fontsig;
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMLangFontLink, iface);
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
old_font = SelectObject(hDC,hFont);
|
|
GetTextCharsetInfo(hDC,&fontsig, 0);
|
|
SelectObject(hDC,old_font);
|
|
|
|
*pdwCodePages = fontsig.fsCsb[0];
|
|
TRACE("CodePages is 0x%lx\n",fontsig.fsCsb[0]);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_MapFont(
|
|
IMLangFontLink* iface,
|
|
HDC hDC,
|
|
DWORD dwCodePages,
|
|
HFONT hSrcFont,
|
|
HFONT* phDestFont)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_ReleaseFont(
|
|
IMLangFontLink* iface,
|
|
HFONT hFont)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMLangFontLink_ResetFontMapping(
|
|
IMLangFontLink* iface)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
static const IMLangFontLinkVtbl IMLangFontLink_vtbl =
|
|
{
|
|
fnIMLangFontLink_QueryInterface,
|
|
fnIMLangFontLink_AddRef,
|
|
fnIMLangFontLink_Release,
|
|
fnIMLangFontLink_GetCharCodePages,
|
|
fnIMLangFontLink_GetStrCodePages,
|
|
fnIMLangFontLink_CodePageToCodePages,
|
|
fnIMLangFontLink_CodePagesToCodePage,
|
|
fnIMLangFontLink_GetFontCodePages,
|
|
fnIMLangFontLink_MapFont,
|
|
fnIMLangFontLink_ReleaseFont,
|
|
fnIMLangFontLink_ResetFontMapping,
|
|
};
|
|
|
|
/******************************************************************************/
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_QueryInterface(
|
|
IMultiLanguage* iface,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
|
|
return MLang_QueryInterface( This, riid, ppvObject );
|
|
}
|
|
|
|
static ULONG WINAPI fnIMultiLanguage_AddRef( IMultiLanguage* iface )
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
|
|
return IMLangFontLink_AddRef( ((IMLangFontLink*)This) );
|
|
}
|
|
|
|
static ULONG WINAPI fnIMultiLanguage_Release( IMultiLanguage* iface )
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
|
|
return IMLangFontLink_Release( ((IMLangFontLink*)This) );
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetNumberOfCodePageInfo(
|
|
IMultiLanguage* iface,
|
|
UINT* pcCodePage)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetCodePageInfo(
|
|
IMultiLanguage* iface,
|
|
UINT uiCodePage,
|
|
PMIMECPINFO pCodePageInfo)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetFamilyCodePage(
|
|
IMultiLanguage* iface,
|
|
UINT uiCodePage,
|
|
UINT* puiFamilyCodePage)
|
|
{
|
|
return GetFamilyCodePage(uiCodePage, puiFamilyCodePage);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_EnumCodePages(
|
|
IMultiLanguage* iface,
|
|
DWORD grfFlags,
|
|
IEnumCodePage** ppEnumCodePage)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
|
|
TRACE("%p %08lx %p\n", This, grfFlags, ppEnumCodePage);
|
|
|
|
return EnumCodePage_create( This, grfFlags, 0, ppEnumCodePage );
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetCharsetInfo(
|
|
IMultiLanguage* iface,
|
|
BSTR Charset,
|
|
PMIMECSETINFO pCharsetInfo)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_IsConvertible(
|
|
IMultiLanguage* iface,
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding)
|
|
{
|
|
return IsConvertINetStringAvailable(dwSrcEncoding, dwDstEncoding);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_ConvertString(
|
|
IMultiLanguage* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding,
|
|
BYTE* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
BYTE* pDstStr,
|
|
UINT* pcDstSize)
|
|
{
|
|
return ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding,
|
|
(LPCSTR)pSrcStr, (LPINT)pcSrcSize, (LPSTR)pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_ConvertStringToUnicode(
|
|
IMultiLanguage* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwEncoding,
|
|
CHAR* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
WCHAR* pDstStr,
|
|
UINT* pcDstSize)
|
|
{
|
|
return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding,
|
|
(LPCSTR)pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_ConvertStringFromUnicode(
|
|
IMultiLanguage* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwEncoding,
|
|
WCHAR* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
CHAR* pDstStr,
|
|
UINT* pcDstSize)
|
|
{
|
|
return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding,
|
|
pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_ConvertStringReset(
|
|
IMultiLanguage* iface)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetRfc1766FromLcid(
|
|
IMultiLanguage* iface,
|
|
LCID Locale,
|
|
BSTR* pbstrRfc1766)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetLcidFromRfc1766(
|
|
IMultiLanguage* iface,
|
|
LCID* pLocale,
|
|
BSTR bstrRfc1766)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
typedef struct tagEnumRfc1766_impl
|
|
{
|
|
const IEnumRfc1766Vtbl *vtbl_IEnumRfc1766;
|
|
LONG ref;
|
|
RFC1766INFO *info;
|
|
DWORD total, pos;
|
|
} EnumRfc1766_impl;
|
|
|
|
static HRESULT WINAPI fnIEnumRfc1766_QueryInterface(
|
|
IEnumRfc1766 *iface,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
|
|
TRACE("%p -> %s\n", This, debugstr_guid(riid) );
|
|
|
|
if (IsEqualGUID(riid, &IID_IUnknown)
|
|
|| IsEqualGUID(riid, &IID_IEnumRfc1766))
|
|
{
|
|
IEnumRfc1766_AddRef(iface);
|
|
TRACE("Returning IID_IEnumRfc1766 %p ref = %ld\n", This, This->ref);
|
|
*ppvObject = &(This->vtbl_IEnumRfc1766);
|
|
return S_OK;
|
|
}
|
|
|
|
WARN("(%p) -> (%s,%p), not found\n",This,debugstr_guid(riid),ppvObject);
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI fnIEnumRfc1766_AddRef(
|
|
IEnumRfc1766 *iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
static ULONG WINAPI fnIEnumRfc1766_Release(
|
|
IEnumRfc1766 *iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("%p ref = %ld\n", This, ref);
|
|
if (ref == 0)
|
|
{
|
|
TRACE("Destroying %p\n", This);
|
|
HeapFree(GetProcessHeap(), 0, This->info);
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
}
|
|
return ref;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumRfc1766_Clone(
|
|
IEnumRfc1766 *iface,
|
|
IEnumRfc1766 **ppEnum)
|
|
{
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
FIXME("%p %p\n", This, ppEnum);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumRfc1766_Next(
|
|
IEnumRfc1766 *iface,
|
|
ULONG celt,
|
|
PRFC1766INFO rgelt,
|
|
ULONG *pceltFetched)
|
|
{
|
|
ULONG i;
|
|
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
TRACE("%p %lu %p %p\n", This, celt, rgelt, pceltFetched);
|
|
|
|
if (!pceltFetched) return S_FALSE;
|
|
*pceltFetched = 0;
|
|
|
|
if (!rgelt) return S_FALSE;
|
|
|
|
if (This->pos + celt > This->total)
|
|
celt = This->total - This->pos;
|
|
|
|
if (!celt) return S_FALSE;
|
|
|
|
memcpy(rgelt, This->info + This->pos, celt * sizeof(RFC1766INFO));
|
|
*pceltFetched = celt;
|
|
This->pos += celt;
|
|
|
|
for (i = 0; i < celt; i++)
|
|
{
|
|
TRACE("#%lu: %08lx %s %s\n",
|
|
i, rgelt[i].lcid,
|
|
wine_dbgstr_w(rgelt[i].wszRfc1766),
|
|
wine_dbgstr_w(rgelt[i].wszLocaleName));
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumRfc1766_Reset(
|
|
IEnumRfc1766 *iface)
|
|
{
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
TRACE("%p\n", This);
|
|
|
|
This->pos = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIEnumRfc1766_Skip(
|
|
IEnumRfc1766 *iface,
|
|
ULONG celt)
|
|
{
|
|
ICOM_THIS_MULTI(EnumRfc1766_impl, vtbl_IEnumRfc1766, iface);
|
|
TRACE("%p %lu\n", This, celt);
|
|
|
|
if (celt >= This->total) return S_FALSE;
|
|
|
|
This->pos += celt;
|
|
return S_OK;
|
|
}
|
|
|
|
static const IEnumRfc1766Vtbl IEnumRfc1766_vtbl =
|
|
{
|
|
fnIEnumRfc1766_QueryInterface,
|
|
fnIEnumRfc1766_AddRef,
|
|
fnIEnumRfc1766_Release,
|
|
fnIEnumRfc1766_Clone,
|
|
fnIEnumRfc1766_Next,
|
|
fnIEnumRfc1766_Reset,
|
|
fnIEnumRfc1766_Skip
|
|
};
|
|
|
|
struct enum_locales_data
|
|
{
|
|
RFC1766INFO *info;
|
|
DWORD total, allocated;
|
|
};
|
|
|
|
static BOOL CALLBACK enum_locales_proc(LPWSTR locale)
|
|
{
|
|
DWORD n;
|
|
WCHAR *end;
|
|
struct enum_locales_data *data = TlsGetValue(MLANG_tls_index);
|
|
RFC1766INFO *info;
|
|
|
|
TRACE("%s\n", debugstr_w(locale));
|
|
|
|
if (data->total >= data->allocated)
|
|
{
|
|
data->allocated += 32;
|
|
data->info = HeapReAlloc(GetProcessHeap(), 0, data->info, data->allocated * sizeof(RFC1766INFO));
|
|
if (!data->info) return FALSE;
|
|
}
|
|
|
|
info = &data->info[data->total];
|
|
|
|
info->lcid = strtolW(locale, &end, 16);
|
|
if (*end) /* invalid number */
|
|
return FALSE;
|
|
|
|
info->wszRfc1766[0] = 0;
|
|
n = GetLocaleInfoW(info->lcid, LOCALE_SISO639LANGNAME, info->wszRfc1766, MAX_RFC1766_NAME);
|
|
if (n && n < MAX_RFC1766_NAME)
|
|
{
|
|
info->wszRfc1766[n - 1] = '-';
|
|
GetLocaleInfoW(info->lcid, LOCALE_SISO3166CTRYNAME, info->wszRfc1766 + n, MAX_RFC1766_NAME - n);
|
|
LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, info->wszRfc1766 + n, -1, info->wszRfc1766 + n, MAX_RFC1766_NAME - n);
|
|
}
|
|
info->wszLocaleName[0] = 0;
|
|
GetLocaleInfoW(info->lcid, LOCALE_SLANGUAGE, info->wszLocaleName, MAX_LOCALE_NAME);
|
|
TRACE("ISO639: %s SLANGUAGE: %s\n", wine_dbgstr_w(info->wszRfc1766), wine_dbgstr_w(info->wszLocaleName));
|
|
|
|
data->total++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static HRESULT EnumRfc1766_create(MLang_impl* mlang, LANGID LangId,
|
|
IEnumRfc1766 **ppEnum)
|
|
{
|
|
EnumRfc1766_impl *rfc;
|
|
struct enum_locales_data data;
|
|
|
|
TRACE("%p, %04x, %p\n", mlang, LangId, ppEnum);
|
|
|
|
rfc = HeapAlloc( GetProcessHeap(), 0, sizeof(EnumRfc1766_impl) );
|
|
rfc->vtbl_IEnumRfc1766 = &IEnumRfc1766_vtbl;
|
|
rfc->ref = 1;
|
|
rfc->pos = 0;
|
|
rfc->total = 0;
|
|
|
|
data.total = 0;
|
|
data.allocated = 32;
|
|
data.info = HeapAlloc(GetProcessHeap(), 0, data.allocated * sizeof(RFC1766INFO));
|
|
if (!data.info) return S_FALSE;
|
|
|
|
TlsSetValue(MLANG_tls_index, &data);
|
|
EnumSystemLocalesW(enum_locales_proc, 0/*LOCALE_SUPPORTED*/);
|
|
TlsSetValue(MLANG_tls_index, NULL);
|
|
|
|
TRACE("enumerated %ld rfc1766 structures\n", data.total);
|
|
|
|
if (!data.total) return FALSE;
|
|
|
|
rfc->info = data.info;
|
|
rfc->total = data.total;
|
|
|
|
*ppEnum = (IEnumRfc1766 *)rfc;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_EnumRfc1766(
|
|
IMultiLanguage *iface,
|
|
IEnumRfc1766 **ppEnumRfc1766)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
|
|
TRACE("%p %p\n", This, ppEnumRfc1766);
|
|
|
|
return EnumRfc1766_create(This, 0, ppEnumRfc1766);
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_GetRfc1766Info(
|
|
IMultiLanguage* iface,
|
|
LCID Locale,
|
|
PRFC1766INFO pRfc1766Info)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage_CreateConvertCharset(
|
|
IMultiLanguage* iface,
|
|
UINT uiSrcCodePage,
|
|
UINT uiDstCodePage,
|
|
DWORD dwProperty,
|
|
IMLangConvertCharset** ppMLangConvertCharset)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const IMultiLanguageVtbl IMultiLanguage_vtbl =
|
|
{
|
|
fnIMultiLanguage_QueryInterface,
|
|
fnIMultiLanguage_AddRef,
|
|
fnIMultiLanguage_Release,
|
|
fnIMultiLanguage_GetNumberOfCodePageInfo,
|
|
fnIMultiLanguage_GetCodePageInfo,
|
|
fnIMultiLanguage_GetFamilyCodePage,
|
|
fnIMultiLanguage_EnumCodePages,
|
|
fnIMultiLanguage_GetCharsetInfo,
|
|
fnIMultiLanguage_IsConvertible,
|
|
fnIMultiLanguage_ConvertString,
|
|
fnIMultiLanguage_ConvertStringToUnicode,
|
|
fnIMultiLanguage_ConvertStringFromUnicode,
|
|
fnIMultiLanguage_ConvertStringReset,
|
|
fnIMultiLanguage_GetRfc1766FromLcid,
|
|
fnIMultiLanguage_GetLcidFromRfc1766,
|
|
fnIMultiLanguage_EnumRfc1766,
|
|
fnIMultiLanguage_GetRfc1766Info,
|
|
fnIMultiLanguage_CreateConvertCharset,
|
|
};
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_QueryInterface(
|
|
IMultiLanguage2* iface,
|
|
REFIID riid,
|
|
void** ppvObject)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
return MLang_QueryInterface( This, riid, ppvObject );
|
|
}
|
|
|
|
static ULONG WINAPI fnIMultiLanguage2_AddRef( IMultiLanguage2* iface )
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
return MLang_AddRef( This );
|
|
}
|
|
|
|
static ULONG WINAPI fnIMultiLanguage2_Release( IMultiLanguage2* iface )
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
return MLang_Release( This );
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfCodePageInfo(
|
|
IMultiLanguage2* iface,
|
|
UINT* pcCodePage)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
TRACE("%p, %p\n", This, pcCodePage);
|
|
|
|
if (!pcCodePage) return S_FALSE;
|
|
|
|
*pcCodePage = This->total_cp;
|
|
return S_OK;
|
|
}
|
|
|
|
static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info)
|
|
{
|
|
CHARSETINFO csi;
|
|
|
|
if (TranslateCharsetInfo((DWORD *)ml_data->family_codepage, &csi, TCI_SRCCODEPAGE))
|
|
mime_cp_info->bGDICharset = csi.ciCharset;
|
|
else
|
|
mime_cp_info->bGDICharset = DEFAULT_CHARSET;
|
|
|
|
mime_cp_info->dwFlags = ml_data->mime_cp_info[index].flags;
|
|
mime_cp_info->uiCodePage = ml_data->mime_cp_info[index].cp;
|
|
mime_cp_info->uiFamilyCodePage = ml_data->family_codepage;
|
|
MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].description, -1,
|
|
mime_cp_info->wszDescription, sizeof(mime_cp_info->wszDescription)/sizeof(WCHAR));
|
|
MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].web_charset, -1,
|
|
mime_cp_info->wszWebCharset, sizeof(mime_cp_info->wszWebCharset)/sizeof(WCHAR));
|
|
MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].header_charset, -1,
|
|
mime_cp_info->wszHeaderCharset, sizeof(mime_cp_info->wszHeaderCharset)/sizeof(WCHAR));
|
|
MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].body_charset, -1,
|
|
mime_cp_info->wszBodyCharset, sizeof(mime_cp_info->wszBodyCharset)/sizeof(WCHAR));
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, ml_data->fixed_font, -1,
|
|
mime_cp_info->wszFixedWidthFont, sizeof(mime_cp_info->wszFixedWidthFont)/sizeof(WCHAR));
|
|
MultiByteToWideChar(CP_ACP, 0, ml_data->proportional_font, -1,
|
|
mime_cp_info->wszProportionalFont, sizeof(mime_cp_info->wszProportionalFont)/sizeof(WCHAR));
|
|
|
|
TRACE("%08lx %u %u %s %s %s %s %s %s %d\n",
|
|
mime_cp_info->dwFlags, mime_cp_info->uiCodePage,
|
|
mime_cp_info->uiFamilyCodePage,
|
|
wine_dbgstr_w(mime_cp_info->wszDescription),
|
|
wine_dbgstr_w(mime_cp_info->wszWebCharset),
|
|
wine_dbgstr_w(mime_cp_info->wszHeaderCharset),
|
|
wine_dbgstr_w(mime_cp_info->wszBodyCharset),
|
|
wine_dbgstr_w(mime_cp_info->wszFixedWidthFont),
|
|
wine_dbgstr_w(mime_cp_info->wszProportionalFont),
|
|
mime_cp_info->bGDICharset);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetCodePageInfo(
|
|
IMultiLanguage2* iface,
|
|
UINT uiCodePage,
|
|
LANGID LangId,
|
|
PMIMECPINFO pCodePageInfo)
|
|
{
|
|
UINT i, n;
|
|
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
TRACE("%p, %u, %04x, %p\n", This, uiCodePage, LangId, pCodePageInfo);
|
|
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
{
|
|
for (n = 0; n < mlang_data[i].number_of_cp; n++)
|
|
{
|
|
if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
|
|
{
|
|
fill_cp_info(&mlang_data[i], n, pCodePageInfo);
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetFamilyCodePage(
|
|
IMultiLanguage2* iface,
|
|
UINT uiCodePage,
|
|
UINT* puiFamilyCodePage)
|
|
{
|
|
return GetFamilyCodePage(uiCodePage, puiFamilyCodePage);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_EnumCodePages(
|
|
IMultiLanguage2* iface,
|
|
DWORD grfFlags,
|
|
LANGID LangId,
|
|
IEnumCodePage** ppEnumCodePage)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
TRACE("%p %08lx %04x %p\n", This, grfFlags, LangId, ppEnumCodePage);
|
|
|
|
return EnumCodePage_create( This, grfFlags, LangId, ppEnumCodePage );
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetCharsetInfo(
|
|
IMultiLanguage2* iface,
|
|
BSTR Charset,
|
|
PMIMECSETINFO pCharsetInfo)
|
|
{
|
|
UINT i, n;
|
|
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
TRACE("%p %s %p\n", This, debugstr_w(Charset), pCharsetInfo);
|
|
|
|
if (!pCharsetInfo) return E_FAIL;
|
|
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
{
|
|
for (n = 0; n < mlang_data[i].number_of_cp; n++)
|
|
{
|
|
WCHAR csetW[MAX_MIMECSET_NAME];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, mlang_data[i].mime_cp_info[n].web_charset, -1, csetW, MAX_MIMECSET_NAME);
|
|
if (!lstrcmpiW(Charset, csetW))
|
|
{
|
|
pCharsetInfo->uiCodePage = mlang_data[i].family_codepage;
|
|
pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp;
|
|
strcpyW(pCharsetInfo->wszCharset, csetW);
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* FIXME:
|
|
* Since we do not support charsets like iso-2022-jp and do not have
|
|
* them in our database as a primary (web_charset) encoding this loop
|
|
* does an attempt to 'approximate' charset name by header_charset.
|
|
*/
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
{
|
|
for (n = 0; n < mlang_data[i].number_of_cp; n++)
|
|
{
|
|
WCHAR csetW[MAX_MIMECSET_NAME];
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, mlang_data[i].mime_cp_info[n].header_charset, -1, csetW, MAX_MIMECSET_NAME);
|
|
if (!lstrcmpiW(Charset, csetW))
|
|
{
|
|
pCharsetInfo->uiCodePage = mlang_data[i].family_codepage;
|
|
pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp;
|
|
strcpyW(pCharsetInfo->wszCharset, csetW);
|
|
return S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_IsConvertible(
|
|
IMultiLanguage2* iface,
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding)
|
|
{
|
|
return IsConvertINetStringAvailable(dwSrcEncoding, dwDstEncoding);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertString(
|
|
IMultiLanguage2* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding,
|
|
BYTE* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
BYTE* pDstStr,
|
|
UINT* pcDstSize)
|
|
{
|
|
return ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding,
|
|
(LPCSTR)pSrcStr, (LPINT)pcSrcSize, (LPSTR)pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicode(
|
|
IMultiLanguage2* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwEncoding,
|
|
CHAR* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
WCHAR* pDstStr,
|
|
UINT* pcDstSize)
|
|
{
|
|
return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding,
|
|
pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringFromUnicode(
|
|
IMultiLanguage2* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwEncoding,
|
|
WCHAR* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
CHAR* pDstStr,
|
|
UINT* pcDstSize)
|
|
{
|
|
return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding,
|
|
pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringReset(
|
|
IMultiLanguage2* iface)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetRfc1766FromLcid(
|
|
IMultiLanguage2* iface,
|
|
LCID Locale,
|
|
BSTR* pbstrRfc1766)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetLcidFromRfc1766(
|
|
IMultiLanguage2* iface,
|
|
LCID* pLocale,
|
|
BSTR bstrRfc1766)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_EnumRfc1766(
|
|
IMultiLanguage2* iface,
|
|
LANGID LangId,
|
|
IEnumRfc1766** ppEnumRfc1766)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage, iface);
|
|
TRACE("%p %p\n", This, ppEnumRfc1766);
|
|
|
|
return EnumRfc1766_create(This, LangId, ppEnumRfc1766);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetRfc1766Info(
|
|
IMultiLanguage2* iface,
|
|
LCID Locale,
|
|
LANGID LangId,
|
|
PRFC1766INFO pRfc1766Info)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_CreateConvertCharset(
|
|
IMultiLanguage2* iface,
|
|
UINT uiSrcCodePage,
|
|
UINT uiDstCodePage,
|
|
DWORD dwProperty,
|
|
IMLangConvertCharset** ppMLangConvertCharset)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringInIStream(
|
|
IMultiLanguage2* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwFlag,
|
|
WCHAR* lpFallBack,
|
|
DWORD dwSrcEncoding,
|
|
DWORD dwDstEncoding,
|
|
IStream* pstmIn,
|
|
IStream* pstmOut)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/*
|
|
* TODO: handle dwFlag and lpFallBack
|
|
*/
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringToUnicodeEx(
|
|
IMultiLanguage2* iface,
|
|
DWORD* pdwMode,
|
|
DWORD dwEncoding,
|
|
CHAR* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
WCHAR* pDstStr,
|
|
UINT* pcDstSize,
|
|
DWORD dwFlag,
|
|
WCHAR* lpFallBack)
|
|
{
|
|
FIXME("\n");
|
|
return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding,
|
|
pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* MultiLanguage2::ConvertStringToUnicodeEx
|
|
*
|
|
* Translates the multibyte string from the specified code page to Unicode.
|
|
*
|
|
* PARAMS
|
|
* see ConvertStringToUnicode
|
|
* dwFlag
|
|
* lpFallBack if dwFlag contains MLCONVCHARF_USEDEFCHAR, lpFallBack string used
|
|
* instead unconvertible characters.
|
|
*
|
|
* RETURNS
|
|
* S_OK Success.
|
|
* S_FALSE The conversion is not supported.
|
|
* E_FAIL Some error has occurred.
|
|
*
|
|
* TODO: handle dwFlag and lpFallBack
|
|
*/
|
|
static HRESULT WINAPI fnIMultiLanguage2_ConvertStringFromUnicodeEx(
|
|
IMultiLanguage2* This,
|
|
DWORD* pdwMode,
|
|
DWORD dwEncoding,
|
|
WCHAR* pSrcStr,
|
|
UINT* pcSrcSize,
|
|
CHAR* pDstStr,
|
|
UINT* pcDstSize,
|
|
DWORD dwFlag,
|
|
WCHAR* lpFallBack)
|
|
{
|
|
FIXME("\n");
|
|
return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding,
|
|
pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_DetectCodepageInIStream(
|
|
IMultiLanguage2* iface,
|
|
DWORD dwFlag,
|
|
DWORD dwPrefWinCodePage,
|
|
IStream* pstmIn,
|
|
DetectEncodingInfo* lpEncoding,
|
|
INT* pnScores)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_DetectInputCodepage(
|
|
IMultiLanguage2* iface,
|
|
DWORD dwFlag,
|
|
DWORD dwPrefWinCodePage,
|
|
CHAR* pSrcStr,
|
|
INT* pcSrcSize,
|
|
DetectEncodingInfo* lpEncoding,
|
|
INT* pnScores)
|
|
{
|
|
FIXME("\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ValidateCodePage(
|
|
IMultiLanguage2* iface,
|
|
UINT uiCodePage,
|
|
HWND hwnd)
|
|
{
|
|
FIXME("%u, %p\n", uiCodePage, hwnd);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetCodePageDescription(
|
|
IMultiLanguage2* iface,
|
|
UINT uiCodePage,
|
|
LCID lcid,
|
|
LPWSTR lpWideCharStr,
|
|
int cchWideChar)
|
|
{
|
|
FIXME("%u, %04lx, %p, %d\n", uiCodePage, lcid, lpWideCharStr, cchWideChar);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_IsCodePageInstallable(
|
|
IMultiLanguage2* iface,
|
|
UINT uiCodePage)
|
|
{
|
|
FIXME("%u\n", uiCodePage);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_SetMimeDBSource(
|
|
IMultiLanguage2* iface,
|
|
MIMECONTF dwSource)
|
|
{
|
|
FIXME("0x%08x\n", dwSource);
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_GetNumberOfScripts(
|
|
IMultiLanguage2* iface,
|
|
UINT* pnScripts)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
TRACE("%p %p\n", This, pnScripts);
|
|
|
|
if (!pnScripts) return S_FALSE;
|
|
|
|
*pnScripts = This->total_scripts;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_EnumScripts(
|
|
IMultiLanguage2* iface,
|
|
DWORD dwFlags,
|
|
LANGID LangId,
|
|
IEnumScript** ppEnumScript)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
TRACE("%p %08lx %04x %p\n", This, dwFlags, LangId, ppEnumScript);
|
|
|
|
return EnumScript_create( This, dwFlags, LangId, ppEnumScript );
|
|
}
|
|
|
|
static HRESULT WINAPI fnIMultiLanguage2_ValidateCodePageEx(
|
|
IMultiLanguage2* iface,
|
|
UINT uiCodePage,
|
|
HWND hwnd,
|
|
DWORD dwfIODControl)
|
|
{
|
|
ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
|
|
FIXME("%p %u %p %08lx: stub!\n", This, uiCodePage, hwnd, dwfIODControl);
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
static const IMultiLanguage2Vtbl IMultiLanguage2_vtbl =
|
|
{
|
|
fnIMultiLanguage2_QueryInterface,
|
|
fnIMultiLanguage2_AddRef,
|
|
fnIMultiLanguage2_Release,
|
|
fnIMultiLanguage2_GetNumberOfCodePageInfo,
|
|
fnIMultiLanguage2_GetCodePageInfo,
|
|
fnIMultiLanguage2_GetFamilyCodePage,
|
|
fnIMultiLanguage2_EnumCodePages,
|
|
fnIMultiLanguage2_GetCharsetInfo,
|
|
fnIMultiLanguage2_IsConvertible,
|
|
fnIMultiLanguage2_ConvertString,
|
|
fnIMultiLanguage2_ConvertStringToUnicode,
|
|
fnIMultiLanguage2_ConvertStringFromUnicode,
|
|
fnIMultiLanguage2_ConvertStringReset,
|
|
fnIMultiLanguage2_GetRfc1766FromLcid,
|
|
fnIMultiLanguage2_GetLcidFromRfc1766,
|
|
fnIMultiLanguage2_EnumRfc1766,
|
|
fnIMultiLanguage2_GetRfc1766Info,
|
|
fnIMultiLanguage2_CreateConvertCharset,
|
|
fnIMultiLanguage2_ConvertStringInIStream,
|
|
fnIMultiLanguage2_ConvertStringToUnicodeEx,
|
|
fnIMultiLanguage2_ConvertStringFromUnicodeEx,
|
|
fnIMultiLanguage2_DetectCodepageInIStream,
|
|
fnIMultiLanguage2_DetectInputCodepage,
|
|
fnIMultiLanguage2_ValidateCodePage,
|
|
fnIMultiLanguage2_GetCodePageDescription,
|
|
fnIMultiLanguage2_IsCodePageInstallable,
|
|
fnIMultiLanguage2_SetMimeDBSource,
|
|
fnIMultiLanguage2_GetNumberOfScripts,
|
|
fnIMultiLanguage2_EnumScripts,
|
|
fnIMultiLanguage2_ValidateCodePageEx,
|
|
};
|
|
|
|
static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
|
{
|
|
MLang_impl *mlang;
|
|
UINT i;
|
|
|
|
TRACE("Creating MultiLanguage object\n");
|
|
|
|
if( pUnkOuter )
|
|
return CLASS_E_NOAGGREGATION;
|
|
|
|
mlang = HeapAlloc( GetProcessHeap(), 0, sizeof (MLang_impl) );
|
|
mlang->vtbl_IMLangFontLink = &IMLangFontLink_vtbl;
|
|
mlang->vtbl_IMultiLanguage = &IMultiLanguage_vtbl;
|
|
mlang->vtbl_IMultiLanguage2 = &IMultiLanguage2_vtbl;
|
|
|
|
mlang->total_cp = 0;
|
|
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
|
|
mlang->total_cp += mlang_data[i].number_of_cp;
|
|
|
|
/* do not enumerate unicode flavours */
|
|
mlang->total_scripts = sizeof(mlang_data)/sizeof(mlang_data[0]) - 1;
|
|
|
|
mlang->ref = 1;
|
|
*ppObj = (LPVOID) mlang;
|
|
TRACE("returning %p\n", mlang);
|
|
|
|
LockModule();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
HRESULT WINAPI DllCanUnloadNow(void)
|
|
{
|
|
return dll_count == 0 ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT WINAPI GetGlobalFontLinkObject(void)
|
|
{
|
|
FIXME("\n");
|
|
return S_FALSE;
|
|
}
|