MLANG: Add stubbed support for IEnumScript interface
Dmitry Timoshkov
dmitry at baikal.ru
Wed Aug 11 08:14:37 CDT 2004
Hello,
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
- add stubbed support for IEnumScript interface
- ConvertINetMultiByteToUnicode/ConvertINetUnicodeToMultiByte should
return required target length if the target buffer is NULL
- add the tests for all the above
- fix IMultiLanguage2 vtable (it was missing ConvertStringFromUnicodeEx)
diff -u cvs/hq/wine/dlls/mlang/mlang.c wine/dlls/mlang/mlang.c
--- cvs/hq/wine/dlls/mlang/mlang.c 2004-08-07 14:02:25.000000000 +0900
+++ wine/dlls/mlang/mlang.c 2004-08-08 16:12:49.000000000 +0900
@@ -412,14 +412,18 @@ HRESULT WINAPI ConvertINetMultiByteToUni
*pcSrcSize = lstrlenW((LPCWSTR)pSrcStr);
*pcDstSize = min(*pcSrcSize, *pcDstSize);
*pcSrcSize *= sizeof(WCHAR);
- memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR));
+ if (pDstStr)
+ memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR));
break;
default:
if (*pcSrcSize == -1)
*pcSrcSize = lstrlenA(pSrcStr);
- *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize);
+ if (pDstStr)
+ *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize);
+ else
+ *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0);
break;
}
@@ -461,14 +465,18 @@ HRESULT WINAPI ConvertINetUnicodeToMulti
if (*pcSrcSize == -1)
*pcSrcSize = lstrlenW(pSrcStr);
*pcDstSize = min(*pcSrcSize * sizeof(WCHAR), *pcDstSize);
- memmove(pDstStr, pSrcStr, *pcDstSize);
+ if (pDstStr)
+ memmove(pDstStr, pSrcStr, *pcDstSize);
break;
default:
if (*pcSrcSize == -1)
*pcSrcSize = lstrlenW(pSrcStr);
- *pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize, NULL, NULL);
+ if (pDstStr)
+ *pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize, NULL, NULL);
+ else
+ *pcDstSize = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0, NULL, NULL);
break;
}
@@ -687,7 +695,7 @@ typedef struct tagMLang_impl
ICOM_VTABLE(IMultiLanguage) *vtbl_IMultiLanguage;
ICOM_VTABLE(IMultiLanguage2) *vtbl_IMultiLanguage2;
DWORD ref;
- DWORD total;
+ DWORD total_cp, total_scripts;
} MLang_impl;
static ULONG WINAPI MLang_AddRef( MLang_impl* This)
@@ -887,6 +895,7 @@ static HRESULT EnumCodePage_create( MLan
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++)
{
@@ -919,6 +928,161 @@ static HRESULT EnumCodePage_create( MLan
/******************************************************************************/
+typedef struct tagEnumScript_impl
+{
+ ICOM_VTABLE(IEnumScript) *vtbl_IEnumScript;
+ DWORD 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 ++(This->ref);
+}
+
+static ULONG WINAPI fnIEnumScript_Release(
+ IEnumScript* iface)
+{
+ ICOM_THIS_MULTI(EnumScript_impl, vtbl_IEnumScript, iface);
+ ULONG ref = --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; /* FIXME: should be += ?? */
+ return S_OK;
+}
+
+static ICOM_VTABLE(IEnumScript) IEnumScript_vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ 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 )
+{
+ static const WCHAR defaultW[] = { 'D','e','f','a','u','l','t',0 };
+ EnumScript_impl *es;
+
+ FIXME("%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;
+ es->total = 1;
+
+ es->script_info = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPTINFO) * es->total);
+
+ /* just a fake for now */
+ es->script_info[0].ScriptId = 0;
+ es->script_info[0].uiCodePage = 0;
+ strcpyW(es->script_info[0].wszDescription, defaultW);
+ es->script_info[0].wszFixedWidthFont[0] = 0;
+ es->script_info[0].wszProportionalFont[0] = 0;
+
+ *ppEnumScript = (IEnumScript *)es;
+
+ return S_OK;
+}
+
+/******************************************************************************/
+
static HRESULT WINAPI fnIMLangFontLink_QueryInterface(
IMLangFontLink* iface,
REFIID riid,
@@ -1260,7 +1424,7 @@ static HRESULT WINAPI fnIMultiLanguage2_
if (!pcCodePage) return S_FALSE;
- *pcCodePage = This->total;
+ *pcCodePage = This->total_cp;
return S_OK;
}
@@ -1489,6 +1653,21 @@ static HRESULT WINAPI fnIMultiLanguage2_
return E_NOTIMPL;
}
+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 E_NOTIMPL;
+}
+
static HRESULT WINAPI fnIMultiLanguage2_DetectCodepageInIStream(
IMultiLanguage2* iface,
DWORD dwFlag,
@@ -1554,8 +1733,13 @@ static HRESULT WINAPI fnIMultiLanguage2_
IMultiLanguage2* iface,
UINT* pnScripts)
{
- FIXME("\n");
- return E_NOTIMPL;
+ 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(
@@ -1564,8 +1748,10 @@ static HRESULT WINAPI fnIMultiLanguage2_
LANGID LangId,
IEnumScript** ppEnumScript)
{
- FIXME("\n");
- return E_NOTIMPL;
+ 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(
@@ -1574,8 +1760,10 @@ static HRESULT WINAPI fnIMultiLanguage2_
HWND hwnd,
DWORD dwfIODControl)
{
- FIXME("\n");
- return E_NOTIMPL;
+ ICOM_THIS_MULTI(MLang_impl, vtbl_IMultiLanguage2, iface);
+ FIXME("%p %u %p %08lx: stub!\n", This, uiCodePage, hwnd, dwfIODControl);
+
+ return S_FALSE;
}
static ICOM_VTABLE(IMultiLanguage2) IMultiLanguage2_vtbl =
@@ -1601,6 +1789,7 @@ static ICOM_VTABLE(IMultiLanguage2) IMul
fnIMultiLanguage2_CreateConvertCharset,
fnIMultiLanguage2_ConvertStringInIStream,
fnIMultiLanguage2_ConvertStringToUnicodeEx,
+ fnIMultiLanguage2_ConvertStringFromUnicodeEx,
fnIMultiLanguage2_DetectCodepageInIStream,
fnIMultiLanguage2_DetectInputCodepage,
fnIMultiLanguage2_ValidateCodePage,
@@ -1624,9 +1813,11 @@ static HRESULT MultiLanguage_create(IUnk
mlang->vtbl_IMultiLanguage = &IMultiLanguage_vtbl;
mlang->vtbl_IMultiLanguage2 = &IMultiLanguage2_vtbl;
- mlang->total = 0;
+ mlang->total_cp = 0;
for (i = 0; i < sizeof(mlang_data)/sizeof(mlang_data[0]); i++)
- mlang->total += mlang_data[i].number_of_cp;
+ mlang->total_cp += mlang_data[i].number_of_cp;
+
+ mlang->total_scripts = 1;
mlang->ref = 1;
*ppObj = (LPVOID) mlang;
diff -u cvs/hq/wine/dlls/mlang/tests/mlang.c wine/dlls/mlang/tests/mlang.c
--- cvs/hq/wine/dlls/mlang/tests/mlang.c 2004-08-05 03:33:06.000000000 +0900
+++ wine/dlls/mlang/tests/mlang.c 2004-08-08 16:15:02.000000000 +0900
@@ -35,6 +35,7 @@
#endif
/*#define DUMP_CP_INFO*/
+/*#define DUMP_SCRIPT_INFO*/
#define TRACE_2 OutputDebugStringA
@@ -45,8 +46,19 @@ static void test_multibyte_to_unicode_tr
WCHAR stringW[] = {'J','u','s','t',' ','a',' ','t','e','s','t',' ','s','t','r','i','n','g',0};
char bufA[256];
WCHAR bufW[256];
- UINT lenA, lenW;
+ UINT lenA, lenW, expected_len;
HRESULT ret;
+ HMODULE hMlang;
+ FARPROC pConvertINetMultiByteToUnicode;
+ FARPROC pConvertINetUnicodeToMultiByte;
+
+ hMlang = LoadLibraryA("mlang.dll");
+ ok(hMlang != 0, "couldn't load mlang.dll\n");
+
+ pConvertINetMultiByteToUnicode = GetProcAddress(hMlang, "ConvertINetMultiByteToUnicode");
+ ok(pConvertINetMultiByteToUnicode != NULL, "couldn't resolve ConvertINetMultiByteToUnicode\n");
+ pConvertINetUnicodeToMultiByte = GetProcAddress(hMlang, "ConvertINetUnicodeToMultiByte");
+ ok(pConvertINetUnicodeToMultiByte != NULL, "couldn't resolve ConvertINetUnicodeToMultiByte\n");
/* IMultiLanguage2_ConvertStringToUnicode tests */
@@ -93,6 +105,33 @@ static void test_multibyte_to_unicode_tr
bufW[lenW] = 0; /* -1 doesn't include 0 terminator */
ok(!lstrcmpA((LPCSTR)bufW, stringA), "bufW/stringA mismatch\n");
+ memset(bufW, 'x', sizeof(bufW));
+ lenA = lstrlenA(stringA);
+ lenW = 0;
+ ret = IMultiLanguage2_ConvertStringToUnicode(iML2, NULL, 1252, stringA, &lenA, NULL, &lenW);
+ ok(ret == S_OK, "IMultiLanguage2_ConvertStringToUnicode failed: %08lx\n", ret);
+ ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
+ expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
+ ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
+
+ memset(bufW, 'x', sizeof(bufW));
+ lenA = lstrlenA(stringA);
+ lenW = sizeof(bufW)/sizeof(bufW[0]);
+ ret = pConvertINetMultiByteToUnicode(NULL, 1252, stringA, &lenA, NULL, &lenW);
+ ok(ret == S_OK, "ConvertINetMultiByteToUnicode failed: %08lx\n", ret);
+ ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
+ expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
+ ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
+
+ memset(bufW, 'x', sizeof(bufW));
+ lenA = lstrlenA(stringA);
+ lenW = 0;
+ ret = pConvertINetMultiByteToUnicode(NULL, 1252, stringA, &lenA, NULL, &lenW);
+ ok(ret == S_OK, "ConvertINetMultiByteToUnicode failed: %08lx\n", ret);
+ ok(lenA == lstrlenA(stringA), "expected lenA %u, got %u\n", lstrlenA(stringA), lenA);
+ expected_len = MultiByteToWideChar(1252, 0, stringA, lenA, NULL, 0);
+ ok(lenW == expected_len, "expected lenW %u, got %u\n", expected_len, lenW);
+
/* IMultiLanguage2_ConvertStringFromUnicode tests */
memset(bufA, 'x', sizeof(bufA));
@@ -138,6 +177,33 @@ static void test_multibyte_to_unicode_tr
bufA[lenA] = 0; /* -1 doesn't include 0 terminator */
bufA[lenA+1] = 0; /* sizeof(WCHAR) */
ok(!lstrcmpW((LPCWSTR)bufA, stringW), "bufA/stringW mismatch\n");
+
+ memset(bufA, 'x', sizeof(bufA));
+ lenW = lstrlenW(stringW);
+ lenA = 0;
+ ret = IMultiLanguage2_ConvertStringFromUnicode(iML2, NULL, 1252, stringW, &lenW, NULL, &lenA);
+ ok(ret == S_OK, "IMultiLanguage2_ConvertStringFromUnicode failed: %08lx\n", ret);
+ ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
+ expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
+ ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
+
+ memset(bufA, 'x', sizeof(bufA));
+ lenW = lstrlenW(stringW);
+ lenA = sizeof(bufA);
+ ret = pConvertINetUnicodeToMultiByte(NULL, 1252, stringW, &lenW, NULL, &lenA);
+ ok(ret == S_OK, "ConvertINetUnicodeToMultiByte failed: %08lx\n", ret);
+ ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
+ expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
+ ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
+
+ memset(bufA, 'x', sizeof(bufA));
+ lenW = lstrlenW(stringW);
+ lenA = 0;
+ ret = pConvertINetUnicodeToMultiByte(NULL, 1252, stringW, &lenW, NULL, &lenA);
+ ok(ret == S_OK, "ConvertINetUnicodeToMultiByte failed: %08lx\n", ret);
+ ok(lenW == lstrlenW(stringW), "expected lenW %u, got %u\n", lstrlenW(stringW), lenW);
+ expected_len = WideCharToMultiByte(1252, 0, stringW, lenW, NULL, 0, NULL, NULL);
+ ok(lenA == expected_len, "expected lenA %u, got %u\n", expected_len, lenA);
}
static void inline cpinfo_cmp(MIMECPINFO *cpinfo1, MIMECPINFO *cpinfo2)
@@ -222,7 +288,7 @@ static void test_EnumCodePages(IMultiLan
n = total * 2;
TRACE_2("Call IEnumCodePage_Next\n");
ret = IEnumCodePage_Next(iEnumCP, n, cpinfo, &n);
- ok(ret == S_OK && n != 0, "IEnumCodePage_Next: expected S_OK, got %08lx/%lu\n", ret, n);
+ ok(ret == S_OK && n != 0, "IEnumCodePage_Next: expected S_OK/!0, got %08lx/%lu\n", ret, n);
trace("flags %08lx, enumerated codepages %lu\n", flags, n);
@@ -310,13 +376,13 @@ static void test_EnumCodePages(IMultiLan
/* now IEnumCodePage_Next should fail, since pointer is at the end */
n = 1;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
- ok(ret == S_FALSE && n == 0, "IEnumCodePage_Next: expected S_OK/0, got %08lx/%lu\n", ret, n);
+ ok(ret == S_FALSE && n == 0, "IEnumCodePage_Next: expected S_FALSE/0, got %08lx/%lu\n", ret, n);
ret = IEnumCodePage_Reset(iEnumCP);
ok(ret == S_OK, "IEnumCodePage_Reset: expected S_OK, got %08lx\n", ret);
n = 0;
ret = IEnumCodePage_Next(iEnumCP, 1, &cpinfo2, &n);
- ok(n == 1 && ret == S_OK, "IEnumCodePage_Next: expected 2/S_OK, got %lu/%08lx\n", n, ret);
+ ok(n == 1 && ret == S_OK, "IEnumCodePage_Next: expected 1/S_OK, got %lu/%08lx\n", n, ret);
cpinfo_cmp(&cpinfo[0], &cpinfo2);
#if 0
@@ -338,6 +404,125 @@ static void test_EnumCodePages(IMultiLan
IEnumCodePage_Release(iEnumCP);
}
+static void inline scriptinfo_cmp(SCRIPTINFO *sinfo1, SCRIPTINFO *sinfo2)
+{
+ ok(sinfo1->ScriptId == sinfo2->ScriptId, "ScriptId mismatch: %d != %d\n", sinfo1->ScriptId, sinfo2->ScriptId);
+ ok(sinfo1->uiCodePage == sinfo2->uiCodePage, "uiCodePage mismatch: %u != %u\n", sinfo1->uiCodePage, sinfo2->uiCodePage);
+ ok(!lstrcmpW(sinfo1->wszDescription, sinfo2->wszDescription), "wszDescription mismatch\n");
+ ok(!lstrcmpW(sinfo1->wszFixedWidthFont, sinfo2->wszFixedWidthFont), "wszFixedWidthFont mismatch\n");
+ ok(!lstrcmpW(sinfo1->wszProportionalFont, sinfo2->wszProportionalFont), "wszProportionalFont mismatch\n");
+}
+
+static void test_EnumScripts(IMultiLanguage2 *iML2, DWORD flags)
+{
+ IEnumScript *iEnumScript = NULL;
+ SCRIPTINFO *sinfo;
+ SCRIPTINFO sinfo2;
+ HRESULT ret;
+ ULONG i, n;
+ UINT total;
+
+ total = 0;
+ TRACE_2("Call IMultiLanguage2_GetNumberOfScripts\n");
+ ret = IMultiLanguage2_GetNumberOfScripts(iML2, &total);
+ ok(ret == S_OK && total != 0, "IMultiLanguage2_GetNumberOfScripts: expected S_OK/!0, got %08lx/%u\n", ret, total);
+
+ trace("total mlang supported scripts %u\n", total);
+
+ TRACE_2("Call IMultiLanguage2_EnumScripts\n");
+ ret = IMultiLanguage2_EnumScripts(iML2, flags, LANG_NEUTRAL, &iEnumScript);
+ trace("IMultiLanguage2_EnumScripts = %08lx, iEnumScript = %p\n", ret, iEnumScript);
+ ok(ret == S_OK && iEnumScript, "IMultiLanguage2_EnumScripts: expected S_OK/!NULL, got %08lx/%p\n", ret, iEnumScript);
+
+ TRACE_2("Call IEnumScript_Reset\n");
+ ret = IEnumScript_Reset(iEnumScript);
+ ok(ret == S_OK, "IEnumScript_Reset: expected S_OK, got %08lx\n", ret);
+ n = 65536;
+ TRACE_2("Call IEnumScript_Next\n");
+ ret = IEnumScript_Next(iEnumScript, 0, NULL, &n);
+ ok(n == 65536 && ret == E_FAIL, "IEnumScript_Next: expected 65536/E_FAIL, got %lu/%08lx\n", n, ret);
+ TRACE_2("Call IEnumScript_Next\n");
+ ret = IEnumScript_Next(iEnumScript, 0, NULL, NULL);
+ ok(ret == E_FAIL, "IEnumScript_Next: expected E_FAIL, got %08lx\n", ret);
+
+ sinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*sinfo) * total * 2);
+
+ n = total * 2;
+ TRACE_2("Call IEnumScript_Next\n");
+ ret = IEnumScript_Next(iEnumScript, 0, sinfo, &n);
+ ok(ret == S_FALSE && n == 0, "IEnumScript_Next: expected S_FALSE/0, got %08lx/%lu\n", ret, n);
+
+ n = total * 2;
+ TRACE_2("Call IEnumScript_Next\n");
+ ret = IEnumScript_Next(iEnumScript, n, sinfo, &n);
+ ok(ret == S_OK && n != 0, "IEnumScript_Next: expected S_OK, got %08lx/%lu\n", ret, n);
+
+ trace("flags %08lx, enumerated scripts %lu\n", flags, n);
+
+ if (!flags)
+ {
+ ok(n == total, "IEnumScript_Next: expected %u, got %lu", total, n);
+ flags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM;
+ }
+
+ total = n;
+
+ for (i = 0; i < n; i++)
+ {
+ CPINFOEXA cpinfoex;
+#ifdef DUMP_SCRIPT_INFO
+ trace("SCRIPTINFO #%lu:\n"
+ "ScriptId %08lx\n"
+ "uiCodePage %u\n"
+ "wszDescription %s\n"
+ "wszFixedWidthFont %s\n"
+ "wszProportionalFont %s\n\n",
+ i,
+ sinfo[i].ScriptId,
+ sinfo[i].uiCodePage,
+ wine_dbgstr_w(sinfo[i].wszDescription),
+ wine_dbgstr_w(sinfo[i].wszFixedWidthFont),
+ wine_dbgstr_w(sinfo[i].wszProportionalFont));
+#endif
+ if (GetCPInfoExA(sinfo[i].uiCodePage, 0, &cpinfoex))
+ trace("CodePage %u name: %s\n", sinfo[i].uiCodePage, cpinfoex.CodePageName);
+ else
+ trace("GetCPInfoExA failed for cp %u\n", sinfo[i].uiCodePage);
+
+ trace("---\n");
+ }
+
+ /* now IEnumScript_Next should fail, since pointer is at the end */
+ n = 1;
+ ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
+ ok(ret == S_FALSE && n == 0, "IEnumScript_Next: expected S_FALSE/0, got %08lx/%lu\n", ret, n);
+
+ ret = IEnumScript_Reset(iEnumScript);
+ ok(ret == S_OK, "IEnumScript_Reset: expected S_OK, got %08lx\n", ret);
+ n = 0;
+ ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
+ ok(n == 1 && ret == S_OK, "IEnumScript_Next: expected 1/S_OK, got %lu/%08lx\n", n, ret);
+ scriptinfo_cmp(&sinfo[0], &sinfo2);
+
+#if 0
+ /* Due to a bug in MS' implementation of IEnumScript_Skip
+ * it's not used here.
+ */
+ ret = IEnumScript_Skip(iEnumScript, 1);
+ ok(ret == S_OK, "IEnumScript_Skip: expected S_OK, got %08lx\n", ret);
+#endif
+ for (i = 0; i < total - 1; i++)
+ {
+ n = 0;
+ ret = IEnumScript_Next(iEnumScript, 1, &sinfo2, &n);
+ ok(n == 1 && ret == S_OK, "IEnumScript_Next: expected 1/S_OK, got %lu/%08lx\n", n, ret);
+ scriptinfo_cmp(&sinfo[i + 1], &sinfo2);
+ }
+
+ HeapFree(GetProcessHeap(), 0, sinfo);
+ IEnumScript_Release(iEnumScript);
+}
+
START_TEST(mlang)
{
IMultiLanguage2 *iML2 = NULL;
@@ -359,6 +544,10 @@ START_TEST(mlang)
/* FIXME: why MIMECONTF_MIME_REGISTRY returns 0 of supported codepages? */
/*test_EnumCodePages(iML2, MIMECONTF_MIME_REGISTRY);*/
+ test_EnumScripts(iML2, 0);
+ test_EnumScripts(iML2, SCRIPTCONTF_SCRIPT_USER);
+ test_EnumScripts(iML2, SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM);
+
TRACE_2("Call IMultiLanguage2_IsConvertible\n");
ret = IMultiLanguage2_IsConvertible(iML2, CP_UTF8, CP_UNICODE);
ok(ret == S_OK, "IMultiLanguage2_IsConvertible(CP_UTF8 -> CP_UNICODE) = %08lx\n", ret);
diff -u cvs/hq/wine/include/mlang.h wine/include/mlang.h
--- cvs/hq/wine/include/mlang.h 2004-08-07 14:02:27.000000000 +0900
+++ wine/include/mlang.h 2004-08-07 16:07:38.000000000 +0900
@@ -346,14 +346,78 @@ typedef struct IEnumScript IEnumScript;
#define MAX_SCRIPT_NAME (48)
+#define MAX_MIMEFACE_NAME (32)
+
typedef BYTE SCRIPT_ID;
+typedef __int64 SCRIPT_IDS;
+
+typedef enum tagSCRIPTCONTF {
+ sidDefault = 0,
+ sidMerge = sidDefault + 1,
+ sidAsciiSym = sidMerge + 1,
+ sidAsciiLatin = sidAsciiSym + 1,
+ sidLatin = sidAsciiLatin + 1,
+ sidGreek = sidLatin + 1,
+ sidCyrillic = sidGreek + 1,
+ sidArmenian = sidCyrillic + 1,
+ sidHebrew = sidArmenian + 1,
+ sidArabic = sidHebrew + 1,
+ sidDevanagari = sidArabic + 1,
+ sidBengali = sidDevanagari + 1,
+ sidGurmukhi = sidBengali + 1,
+ sidGujarati = sidGurmukhi + 1,
+ sidOriya = sidGujarati + 1,
+ sidTamil = sidOriya + 1,
+ sidTelugu = sidTamil + 1,
+ sidKannada = sidTelugu + 1,
+ sidMalayalam = sidKannada + 1,
+ sidThai = sidMalayalam + 1,
+ sidLao = sidThai + 1,
+ sidTibetan = sidLao + 1,
+ sidGeorgian = sidTibetan + 1,
+ sidHangul = sidGeorgian + 1,
+ sidKana = sidHangul + 1,
+ sidBopomofo = sidKana + 1,
+ sidHan = sidBopomofo + 1,
+ sidEthiopic = sidHan + 1,
+ sidCanSyllabic = sidEthiopic + 1,
+ sidCherokee = sidCanSyllabic + 1,
+ sidYi = sidCherokee + 1,
+ sidBraille = sidYi + 1,
+ sidRunic = sidBraille + 1,
+ sidOgham = sidRunic + 1,
+ sidSinhala = sidOgham + 1,
+ sidSyriac = sidSinhala + 1,
+ sidBurmese = sidSyriac + 1,
+ sidKhmer = sidBurmese + 1,
+ sidThaana = sidKhmer + 1,
+ sidMongolian = sidThaana + 1,
+ sidUserDefined = sidMongolian + 1,
+ sidLim = sidUserDefined + 1,
+ sidFEFirst = sidHangul,
+ sidFELast = sidHan
+} SCRIPTCONTF;
+
+typedef enum tagSCRIPTFONTCONTF {
+ SCRIPTCONTF_FIXED_FONT = 0x1,
+ SCRIPTCONTF_PROPORTIONAL_FONT = 0x2,
+ SCRIPTCONTF_SCRIPT_USER = 0x10000,
+ SCRIPTCONTF_SCRIPT_HIDE = 0x20000,
+ SCRIPTCONTF_SCRIPT_SYSTEM = 0x40000
+} SCRIPTFONTCONTF;
+
+typedef struct tagSCRIPFONTINFO {
+ SCRIPT_IDS scripts;
+ WCHAR wszFont[32];
+} SCRIPTFONTINFO, *PSCRIPTFONTINFO;
+
typedef struct tagSCRIPTINFO {
SCRIPT_ID ScriptId;
UINT uiCodePage;
WCHAR wszDescription[48];
- WCHAR wszFixedWidthFont[1];
- WCHAR wszProportionalFont[1];
+ WCHAR wszFixedWidthFont[32];
+ WCHAR wszProportionalFont[32];
} SCRIPTINFO, *PSCRIPTINFO;
/*****************************************************************************
@@ -489,8 +553,6 @@ typedef struct IEnumCodePage IEnumCodePa
#define MAX_MIMECSET_NAME (50)
-#define MAX_MIMEFACE_NAME (32)
-
typedef enum tagMIMECONTF {
MIMECONTF_MAILNEWS = 0x1,
MIMECONTF_BROWSER = 0x2,
@@ -1501,6 +1563,16 @@ struct IMultiLanguage2 : public IUnknown
DWORD dwFlag,
WCHAR* lpFallBack) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ConvertStringFromUnicodeEx(
+ DWORD* pdwMode,
+ DWORD dwEncoding,
+ WCHAR* pSrcStr,
+ UINT* pcSrcSize,
+ CHAR* pDstStr,
+ UINT* pcDstSize,
+ DWORD dwFlag,
+ WCHAR* lpFallBack) = 0;
+
virtual HRESULT STDMETHODCALLTYPE DetectCodepageInIStream(
DWORD dwFlag,
DWORD dwPrefWinCodePage,
@@ -1678,6 +1750,17 @@ struct IMultiLanguage2Vtbl {
DWORD dwFlag,
WCHAR* lpFallBack);
+ HRESULT (STDMETHODCALLTYPE *ConvertStringFromUnicodeEx)(
+ IMultiLanguage2* This,
+ DWORD* pdwMode,
+ DWORD dwEncoding,
+ WCHAR* pSrcStr,
+ UINT* pcSrcSize,
+ CHAR* pDstStr,
+ UINT* pcDstSize,
+ DWORD dwFlag,
+ WCHAR* lpFallBack);
+
HRESULT (STDMETHODCALLTYPE *DetectCodepageInIStream)(
IMultiLanguage2* This,
DWORD dwFlag,
@@ -1755,6 +1838,7 @@ struct IMultiLanguage2Vtbl {
#define IMultiLanguage2_CreateConvertCharset(p,a,b,c,d) (p)->lpVtbl->CreateConvertCharset(p,a,b,c,d)
#define IMultiLanguage2_ConvertStringInIStream(p,a,b,c,d,e,f,g) (p)->lpVtbl->ConvertStringInIStream(p,a,b,c,d,e,f,g)
#define IMultiLanguage2_ConvertStringToUnicodeEx(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->ConvertStringToUnicodeEx(p,a,b,c,d,e,f,g,h)
+#define IMultiLanguage2_ConvertStringFromUnicodeEx(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->ConvertStringFromUnicodeEx(p,a,b,c,d,e,f,g,h)
#define IMultiLanguage2_DetectCodepageInIStream(p,a,b,c,d,e) (p)->lpVtbl->DetectCodepageInIStream(p,a,b,c,d,e)
#define IMultiLanguage2_DetectInputCodepage(p,a,b,c,d,e,f) (p)->lpVtbl->DetectInputCodepage(p,a,b,c,d,e,f)
#define IMultiLanguage2_ValidateCodePage(p,a,b) (p)->lpVtbl->ValidateCodePage(p,a,b)
@@ -1791,6 +1875,7 @@ struct IMultiLanguage2Vtbl {
STDMETHOD_(HRESULT,CreateConvertCharset)(THIS_ UINT uiSrcCodePage, UINT uiDstCodePage, DWORD dwProperty, IMLangConvertCharset** ppMLangConvertCharset) PURE; \
STDMETHOD_(HRESULT,ConvertStringInIStream)(THIS_ DWORD* pdwMode, DWORD dwFlag, WCHAR* lpFallBack, DWORD dwSrcEncoding, DWORD dwDstEncoding, IStream* pstmIn, IStream* pstmOut) PURE; \
STDMETHOD_(HRESULT,ConvertStringToUnicodeEx)(THIS_ DWORD* pdwMode, DWORD dwEncoding, CHAR* pSrcStr, UINT* pcSrcSize, WCHAR* pDstStr, UINT* pcDstSize, DWORD dwFlag, WCHAR* lpFallBack) PURE; \
+ STDMETHOD_(HRESULT,ConvertStringFromUnicodeEx)(THIS_ DWORD* pdwMode, DWORD dwEncoding, WCHAR* pSrcStr, UINT* pcSrcSize, CHAR* pDstStr, UINT* pcDstSize, DWORD dwFlag, WCHAR* lpFallBack) PURE; \
STDMETHOD_(HRESULT,DetectCodepageInIStream)(THIS_ DWORD dwFlag, DWORD dwPrefWinCodePage, IStream* pstmIn, DetectEncodingInfo* lpEncoding, INT* pnScores) PURE; \
STDMETHOD_(HRESULT,DetectInputCodepage)(THIS_ DWORD dwFlag, DWORD dwPrefWinCodePage, CHAR* pSrcStr, INT* pcSrcSize, DetectEncodingInfo* lpEncoding, INT* pnScores) PURE; \
STDMETHOD_(HRESULT,ValidateCodePage)(THIS_ UINT uiCodePage, HWND hwnd) PURE; \
@@ -1980,6 +2065,21 @@ void __RPC_STUB IMultiLanguage2_ConvertS
struct IRpcChannelBuffer* pRpcChannelBuffer,
PRPC_MESSAGE pRpcMessage,
DWORD* pdwStubPhase);
+HRESULT CALLBACK IMultiLanguage2_ConvertStringFromUnicodeEx_Proxy(
+ IMultiLanguage2* This,
+ DWORD* pdwMode,
+ DWORD dwEncoding,
+ WCHAR* pSrcStr,
+ UINT* pcSrcSize,
+ CHAR* pDstStr,
+ UINT* pcDstSize,
+ DWORD dwFlag,
+ WCHAR* lpFallBack);
+void __RPC_STUB IMultiLanguage2_ConvertStringFromUnicodeEx_Stub(
+ struct IRpcStubBuffer* This,
+ struct IRpcChannelBuffer* pRpcChannelBuffer,
+ PRPC_MESSAGE pRpcMessage,
+ DWORD* pdwStubPhase);
HRESULT CALLBACK IMultiLanguage2_DetectCodepageInIStream_Proxy(
IMultiLanguage2* This,
DWORD dwFlag,
@@ -2088,6 +2188,7 @@ DEFINE_GUID(IID_IMLangFontLink, 0x359F34
DEFINE_GUID(IID_IMultiLanguage2, 0xDCCFC164,0x2B38,0x11d2,0xB7,0xEC,0x00,0xC0,0x4F,0x8F,0x5D,0x9A);
DEFINE_GUID(IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);
DEFINE_GUID(IID_IEnumCodePage, 0x275c23e3,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);
+DEFINE_GUID(IID_IEnumScript, 0xae5f1430,0x388b,0x11d2,0x83,0x80,0x00,0xc0,0x4f,0x8f,0x5d,0xa1);
#ifdef __cplusplus
}
#endif
diff -u cvs/hq/wine/include/mlang.idl wine/include/mlang.idl
--- cvs/hq/wine/include/mlang.idl 2004-08-07 14:02:27.000000000 +0900
+++ wine/include/mlang.idl 2004-08-07 16:07:30.000000000 +0900
@@ -79,8 +79,73 @@ interface IMLangFontLink : IMLangCodePag
interface IEnumScript : IUnknown
{
const USHORT MAX_SCRIPT_NAME = 48;
+ const USHORT MAX_MIMEFACE_NAME = 32;
typedef BYTE SCRIPT_ID;
+ typedef __int64 SCRIPT_IDS;
+
+ typedef enum tagSCRIPTCONTF
+ {
+ sidDefault = 0,
+ sidMerge = sidDefault + 1,
+ sidAsciiSym = sidMerge + 1,
+ sidAsciiLatin = sidAsciiSym + 1,
+ sidLatin = sidAsciiLatin + 1,
+ sidGreek = sidLatin + 1,
+ sidCyrillic = sidGreek + 1,
+ sidArmenian = sidCyrillic + 1,
+ sidHebrew = sidArmenian + 1,
+ sidArabic = sidHebrew + 1,
+ sidDevanagari = sidArabic + 1,
+ sidBengali = sidDevanagari + 1,
+ sidGurmukhi = sidBengali + 1,
+ sidGujarati = sidGurmukhi + 1,
+ sidOriya = sidGujarati + 1,
+ sidTamil = sidOriya + 1,
+ sidTelugu = sidTamil + 1,
+ sidKannada = sidTelugu + 1,
+ sidMalayalam = sidKannada + 1,
+ sidThai = sidMalayalam + 1,
+ sidLao = sidThai + 1,
+ sidTibetan = sidLao + 1,
+ sidGeorgian = sidTibetan + 1,
+ sidHangul = sidGeorgian + 1,
+ sidKana = sidHangul + 1,
+ sidBopomofo = sidKana + 1,
+ sidHan = sidBopomofo + 1,
+ sidEthiopic = sidHan + 1,
+ sidCanSyllabic = sidEthiopic + 1,
+ sidCherokee = sidCanSyllabic + 1,
+ sidYi = sidCherokee + 1,
+ sidBraille = sidYi + 1,
+ sidRunic = sidBraille + 1,
+ sidOgham = sidRunic + 1,
+ sidSinhala = sidOgham + 1,
+ sidSyriac = sidSinhala + 1,
+ sidBurmese = sidSyriac + 1,
+ sidKhmer = sidBurmese + 1,
+ sidThaana = sidKhmer + 1,
+ sidMongolian = sidThaana + 1,
+ sidUserDefined = sidMongolian + 1,
+ sidLim = sidUserDefined + 1,
+ sidFEFirst = sidHangul,
+ sidFELast = sidHan
+ } SCRIPTCONTF;
+
+ typedef enum tagSCRIPTFONTCONTF
+ {
+ SCRIPTCONTF_FIXED_FONT = 0x1,
+ SCRIPTCONTF_PROPORTIONAL_FONT = 0x2,
+ SCRIPTCONTF_SCRIPT_USER = 0x10000,
+ SCRIPTCONTF_SCRIPT_HIDE = 0x20000,
+ SCRIPTCONTF_SCRIPT_SYSTEM = 0x40000
+ } SCRIPTFONTCONTF;
+
+ typedef struct tagSCRIPFONTINFO
+ {
+ SCRIPT_IDS scripts;
+ WCHAR wszFont[MAX_MIMEFACE_NAME];
+ } SCRIPTFONTINFO, *PSCRIPTFONTINFO;
typedef struct tagSCRIPTINFO {
SCRIPT_ID ScriptId;
@@ -112,7 +177,6 @@ interface IEnumCodePage : IUnknown
{
const USHORT MAX_MIMECP_NAME = 64;
const USHORT MAX_MIMECSET_NAME = 50;
- const USHORT MAX_MIMEFACE_NAME = 32;
typedef enum tagMIMECONTF
{
@@ -418,6 +482,16 @@ interface IMultiLanguage2 : IUnknown
[in] DWORD dwFlag,
[in] WCHAR *lpFallBack);
+ HRESULT ConvertStringFromUnicodeEx(
+ [in,out] DWORD *pdwMode,
+ [in] DWORD dwEncoding,
+ [in] WCHAR *pSrcStr,
+ [in,out] UINT *pcSrcSize,
+ [in] CHAR *pDstStr,
+ [in,out] UINT *pcDstSize,
+ [in] DWORD dwFlag,
+ [in] WCHAR *lpFallBack);
+
HRESULT DetectCodepageInIStream(
[in] DWORD dwFlag,
[in] DWORD dwPrefWinCodePage,
@@ -482,3 +556,4 @@ cpp_quote("DEFINE_GUID(IID_IMLangFontLin
cpp_quote("DEFINE_GUID(IID_IMultiLanguage2, 0xDCCFC164,0x2B38,0x11d2,0xB7,0xEC,0x00,0xC0,0x4F,0x8F,0x5D,0x9A);")
cpp_quote("DEFINE_GUID(IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);")
cpp_quote("DEFINE_GUID(IID_IEnumCodePage, 0x275c23e3,0x3747,0x11d0,0x9f,0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);")
+cpp_quote("DEFINE_GUID(IID_IEnumScript, 0xae5f1430,0x388b,0x11d2,0x83,0x80,0x00,0xc0,0x4f,0x8f,0x5d,0xa1);")
diff -u cvs/hq/wine/programs/winetest/Makefile.in wine/programs/winetest/Makefile.in
--- cvs/hq/wine/programs/winetest/Makefile.in 2004-07-27 23:17:16.000000000 +0900
+++ wine/programs/winetest/Makefile.in 2004-08-07 17:00:02.000000000 +0900
@@ -26,6 +26,7 @@ TESTS = \
iphlpapi \
kernel32 \
mapi32 \
+ mlang \
msacm32 \
msvcrt \
msvcrtd \
@@ -93,6 +94,8 @@ kernel32_test.exe$(DLLEXT): $(DLLDIR)/ke
cp $(DLLDIR)/kernel/tests/kernel32_test.exe$(DLLEXT) $@ && $(STRIP) $@
mapi32_test.exe$(DLLEXT): $(DLLDIR)/mapi32/tests/mapi32_test.exe$(DLLEXT)
cp $(DLLDIR)/mapi32/tests/mapi32_test.exe$(DLLEXT) $@ && $(STRIP) $@
+mlang_test.exe$(DLLEXT): $(DLLDIR)/mlang/tests/mlang_test.exe$(DLLEXT)
+ cp $(DLLDIR)/mlang/tests/mlang_test.exe$(DLLEXT) $@ && $(STRIP) $@
msacm32_test.exe$(DLLEXT): $(DLLDIR)/msacm/tests/msacm32_test.exe$(DLLEXT)
cp $(DLLDIR)/msacm/tests/msacm32_test.exe$(DLLEXT) $@ && $(STRIP) $@
msvcrt_test.exe$(DLLEXT): $(DLLDIR)/msvcrt/tests/msvcrt_test.exe$(DLLEXT)
More information about the wine-patches
mailing list