1c2c66affSColin Finck /*
2c2c66affSColin Finck * MLANG Class Factory
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2002 Lionel Ulmer
5c2c66affSColin Finck * Copyright 2003,2004 Mike McCormack
6c2c66affSColin Finck * Copyright 2004,2005 Dmitry Timoshkov
7c2c66affSColin Finck * Copyright 2009 Detlef Riekenberg
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is free software; you can redistribute it and/or
10c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
11c2c66affSColin Finck * License as published by the Free Software Foundation; either
12c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
13c2c66affSColin Finck *
14c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
15c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
16c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17c2c66affSColin Finck * Lesser General Public License for more details.
18c2c66affSColin Finck *
19c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
20c2c66affSColin Finck * License along with this library; if not, write to the Free Software
21c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22c2c66affSColin Finck */
23c2c66affSColin Finck
24c2c66affSColin Finck
25c2c66affSColin Finck #include <stdarg.h>
262c523eefSAmine Khaldi #include <stdio.h>
27c2c66affSColin Finck
28c2c66affSColin Finck #define COBJMACROS
29c2c66affSColin Finck
302c523eefSAmine Khaldi #include "windef.h"
312c523eefSAmine Khaldi #include "winbase.h"
322c523eefSAmine Khaldi #include "wingdi.h"
332c523eefSAmine Khaldi #include "winuser.h"
342c523eefSAmine Khaldi #include "ole2.h"
352c523eefSAmine Khaldi #include "objbase.h"
362c523eefSAmine Khaldi #include "rpcproxy.h"
372c523eefSAmine Khaldi #include "mlang.h"
382c523eefSAmine Khaldi #include "mimeole.h"
39c2c66affSColin Finck
402c523eefSAmine Khaldi #include "wine/debug.h"
412c523eefSAmine Khaldi #include "wine/list.h"
42c2c66affSColin Finck
43c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(mlang);
44c2c66affSColin Finck
452c523eefSAmine Khaldi #include "initguid.h"
46c2c66affSColin Finck
47c2c66affSColin Finck static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj);
48c2c66affSColin Finck static HRESULT MLangConvertCharset_create(IUnknown *outer, void **obj);
49c2c66affSColin Finck static HRESULT EnumRfc1766_create(LANGID LangId, IEnumRfc1766 **ppEnum);
50c2c66affSColin Finck
51c2c66affSColin Finck static HINSTANCE instance;
52c2c66affSColin Finck static DWORD MLANG_tls_index; /* to store various per thead data */
53c2c66affSColin Finck
54c2c66affSColin Finck /* FIXME:
55c2c66affSColin Finck * Under what circumstances HKEY_CLASSES_ROOT\MIME\Database\Codepage and
56c2c66affSColin Finck * HKEY_CLASSES_ROOT\MIME\Database\Charset are used?
57c2c66affSColin Finck */
58c2c66affSColin Finck
59c2c66affSColin Finck typedef struct
60c2c66affSColin Finck {
61c2c66affSColin Finck const char *description;
62c2c66affSColin Finck UINT cp;
63c2c66affSColin Finck DWORD flags;
64c2c66affSColin Finck const char *web_charset;
65c2c66affSColin Finck const char *header_charset;
66c2c66affSColin Finck const char *body_charset;
67c2c66affSColin Finck const WCHAR *alias;
68c2c66affSColin Finck } MIME_CP_INFO;
69c2c66affSColin Finck
70c2c66affSColin Finck /* These data are based on the codepage info in libs/unicode/cpmap.pl */
71c2c66affSColin Finck /* FIXME: Add 28604 (Celtic), 28606 (Balkan) */
72c2c66affSColin Finck
73c2c66affSColin Finck static const MIME_CP_INFO arabic_cp[] =
74c2c66affSColin Finck {
75c2c66affSColin Finck { "Arabic (864)",
76c2c66affSColin Finck 864, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
77c2c66affSColin Finck MIMECONTF_MIME_LATEST,
78c2c66affSColin Finck "ibm864", "ibm864", "ibm864" },
79c2c66affSColin Finck { "Arabic (1006)",
80c2c66affSColin Finck 1006, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
81c2c66affSColin Finck MIMECONTF_MIME_LATEST,
82c2c66affSColin Finck "ibm1006", "ibm1006", "ibm1006" },
83c2c66affSColin Finck { "Arabic (Windows)",
84c2c66affSColin Finck 1256, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
85c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
86c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
87c2c66affSColin Finck "windows-1256", "windows-1256", "windows-1256" },
88c2c66affSColin Finck { "Arabic (ISO)",
89c2c66affSColin Finck 28596, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
90c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
91c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
92c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
93c2c66affSColin Finck "iso-8859-6", "iso-8859-6", "iso-8859-6" }
94c2c66affSColin Finck };
95c2c66affSColin Finck static const MIME_CP_INFO baltic_cp[] =
96c2c66affSColin Finck {
97c2c66affSColin Finck { "Baltic (DOS)",
98c2c66affSColin Finck 775, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
99c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
100c2c66affSColin Finck "ibm775", "ibm775", "ibm775" },
101c2c66affSColin Finck { "Baltic (Windows)",
102c2c66affSColin Finck 1257, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
103c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
104c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
105c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
106c2c66affSColin Finck "windows-1257", "windows-1257", "windows-1257" },
107c2c66affSColin Finck { "Baltic (ISO)",
108c2c66affSColin Finck 28594, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
109c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
110c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
111c2c66affSColin Finck MIMECONTF_MIME_LATEST,
112c2c66affSColin Finck "iso-8859-4", "iso-8859-4", "iso-8859-4" },
113c2c66affSColin Finck { "Estonian (ISO)",
114c2c66affSColin Finck 28603, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
115c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
116c2c66affSColin Finck "iso-8859-13", "iso-8859-13", "iso-8859-13" }
117c2c66affSColin Finck };
118c2c66affSColin Finck static const MIME_CP_INFO chinese_simplified_cp[] =
119c2c66affSColin Finck {
1205e2c163fSAmine Khaldi { "Chinese Simplified (Auto-Select)",
1215e2c163fSAmine Khaldi 50936, MIMECONTF_IMPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
1225e2c163fSAmine Khaldi MIMECONTF_MIME_LATEST,
1235e2c163fSAmine Khaldi "_autodetect_chs", "_autodetect_chs", "_autodetect_chs" },
124c2c66affSColin Finck { "Chinese Simplified (GB2312)",
125c2c66affSColin Finck 936, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
1265e2c163fSAmine Khaldi MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID |
127c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
128c2c66affSColin Finck MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
129c2c66affSColin Finck "gb2312", "gb2312", "gb2312" },
1305e2c163fSAmine Khaldi { "Chinese Simplified (GB2312-80)",
1315e2c163fSAmine Khaldi 20936, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
1325e2c163fSAmine Khaldi MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
1335e2c163fSAmine Khaldi "x-cp20936", "x-cp20936", "x-cp20936" },
1345e2c163fSAmine Khaldi { "Chinese Simplified (HZ)",
1355e2c163fSAmine Khaldi 52936, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
1365e2c163fSAmine Khaldi MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
1375e2c163fSAmine Khaldi MIMECONTF_VALID | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
1385e2c163fSAmine Khaldi MIMECONTF_MIME_LATEST,
1395e2c163fSAmine Khaldi "hz-gb-2312", "hz-gb-2312", "hz-gb-2312" },
1405e2c163fSAmine Khaldi { "Chinese Simplified (GB18030)",
1415e2c163fSAmine Khaldi 54936, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
1425e2c163fSAmine Khaldi MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
1435e2c163fSAmine Khaldi MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
1445e2c163fSAmine Khaldi MIMECONTF_MIME_LATEST,
1455e2c163fSAmine Khaldi "GB18030", "GB18030", "GB18030" },
146c2c66affSColin Finck { "Chinese Simplified (GBK)",
147c2c66affSColin Finck 936, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
148c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
149c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
150c2c66affSColin Finck MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
151c2c66affSColin Finck "gbk", "gbk", "gbk" }
152c2c66affSColin Finck };
153c2c66affSColin Finck static const MIME_CP_INFO chinese_traditional_cp[] =
154c2c66affSColin Finck {
1555e2c163fSAmine Khaldi { "Chinese Traditional (Auto-Select)",
1565e2c163fSAmine Khaldi 50950, MIMECONTF_IMPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
1575e2c163fSAmine Khaldi MIMECONTF_MIME_LATEST,
1585e2c163fSAmine Khaldi "_autodetect_cht", "_autodetect_cht", "_autodetect_cht" },
159c2c66affSColin Finck { "Chinese Traditional (Big5)",
160c2c66affSColin Finck 950, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
161c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
1625e2c163fSAmine Khaldi MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
163c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
1645e2c163fSAmine Khaldi "big5", "big5", "big5" },
1655e2c163fSAmine Khaldi { "Chinese Traditional (CNS)",
1665e2c163fSAmine Khaldi 20000, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
1675e2c163fSAmine Khaldi MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
1685e2c163fSAmine Khaldi "x-Chinese-CNS", "x-Chinese-CNS", "x-Chinese-CNS" }
169c2c66affSColin Finck };
170c2c66affSColin Finck static const MIME_CP_INFO central_european_cp[] =
171c2c66affSColin Finck {
172c2c66affSColin Finck { "Central European (DOS)",
173c2c66affSColin Finck 852, MIMECONTF_BROWSER | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_BROWSER |
174c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
175c2c66affSColin Finck MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
176c2c66affSColin Finck "ibm852", "ibm852", "ibm852" },
177c2c66affSColin Finck { "Central European (Windows)",
178c2c66affSColin Finck 1250, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
179c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
180c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
181c2c66affSColin Finck MIMECONTF_MIME_LATEST,
182c2c66affSColin Finck "windows-1250", "windows-1250", "windows-1250" },
183c2c66affSColin Finck { "Central European (Mac)",
184c2c66affSColin Finck 10029, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
185c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
186c2c66affSColin Finck "x-mac-ce", "x-mac-ce", "x-mac-ce" },
187c2c66affSColin Finck { "Central European (ISO)",
188c2c66affSColin Finck 28592, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
189c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
190c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
191c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
192c2c66affSColin Finck "iso-8859-2", "iso-8859-2", "iso-8859-2" }
193c2c66affSColin Finck };
194c2c66affSColin Finck static const MIME_CP_INFO cyrillic_cp[] =
195c2c66affSColin Finck {
196c2c66affSColin Finck { "OEM Cyrillic",
197c2c66affSColin Finck 855, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
198c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
199c2c66affSColin Finck "ibm855", "ibm855", "ibm855" },
200c2c66affSColin Finck { "Cyrillic (DOS)",
201c2c66affSColin Finck 866, MIMECONTF_BROWSER | MIMECONTF_IMPORT | MIMECONTF_SAVABLE_BROWSER |
202c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
203c2c66affSColin Finck MIMECONTF_MIME_LATEST,
204c2c66affSColin Finck "cp866", "cp866", "cp866" },
205c2c66affSColin Finck #if 0 /* Windows has 20866 as an official code page for KOI8-R */
206c2c66affSColin Finck { "Cyrillic (KOI8-R)",
207c2c66affSColin Finck 878, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
208c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
209c2c66affSColin Finck "koi8-r", "koi8-r", "koi8-r" },
210c2c66affSColin Finck #endif
211c2c66affSColin Finck { "Cyrillic (Windows)",
212c2c66affSColin Finck 1251, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
213c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
214c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
215c2c66affSColin Finck "windows-1251", "windows-1251", "windows-1251" },
216c2c66affSColin Finck { "Cyrillic (Mac)",
217c2c66affSColin Finck 10007, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
218c2c66affSColin Finck MIMECONTF_MIME_LATEST,
219c2c66affSColin Finck "x-mac-cyrillic", "x-mac-cyrillic", "x-mac-cyrillic" },
220c2c66affSColin Finck { "Cyrillic (KOI8-R)",
221c2c66affSColin Finck 20866, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
222c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
223c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
224c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
225c2c66affSColin Finck "koi8-r", "koi8-r", "koi8-r" },
226c2c66affSColin Finck { "Cyrillic (KOI8-U)",
227c2c66affSColin Finck 21866, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
228c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
229c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
230c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
231c2c66affSColin Finck "koi8-u", "koi8-u", "koi8-u" },
232c2c66affSColin Finck { "Cyrillic (ISO)",
233c2c66affSColin Finck 28595, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
234c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
235c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
236c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
237c2c66affSColin Finck "iso-8859-5", "iso-8859-5", "iso-8859-5" }
238c2c66affSColin Finck };
239c2c66affSColin Finck static const MIME_CP_INFO greek_cp[] =
240c2c66affSColin Finck {
241c2c66affSColin Finck { "Greek (DOS)",
242c2c66affSColin Finck 737, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
243c2c66affSColin Finck MIMECONTF_MIME_LATEST,
244c2c66affSColin Finck "ibm737", "ibm737", "ibm737" },
245c2c66affSColin Finck { "Greek, Modern (DOS)",
246c2c66affSColin Finck 869, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
247c2c66affSColin Finck MIMECONTF_MIME_LATEST,
248c2c66affSColin Finck "ibm869", "ibm869", "ibm869" },
249c2c66affSColin Finck { "IBM EBCDIC (Greek Modern)",
250c2c66affSColin Finck 875, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
251c2c66affSColin Finck MIMECONTF_MIME_LATEST,
252c2c66affSColin Finck "cp875", "cp875", "cp875" },
253c2c66affSColin Finck { "Greek (Windows)",
254c2c66affSColin Finck 1253, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
255c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
256c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
257c2c66affSColin Finck "windows-1253", "windows-1253", "windows-1253" },
258c2c66affSColin Finck { "Greek (Mac)",
259c2c66affSColin Finck 10006, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
260c2c66affSColin Finck MIMECONTF_MIME_LATEST,
261c2c66affSColin Finck "x-mac-greek", "x-mac-greek", "x-mac-greek" },
262c2c66affSColin Finck { "Greek (ISO)",
263c2c66affSColin Finck 28597, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
264c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
265c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
266c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
267c2c66affSColin Finck "iso-8859-7", "iso-8859-7", "iso-8859-7" }
268c2c66affSColin Finck };
269c2c66affSColin Finck static const MIME_CP_INFO hebrew_cp[] =
270c2c66affSColin Finck {
271c2c66affSColin Finck { "Hebrew (424)",
272c2c66affSColin Finck 424, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
273c2c66affSColin Finck MIMECONTF_MIME_LATEST,
274c2c66affSColin Finck "ibm424", "ibm424", "ibm424" },
275c2c66affSColin Finck { "Hebrew (856)",
276c2c66affSColin Finck 856, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
277c2c66affSColin Finck MIMECONTF_MIME_LATEST,
278c2c66affSColin Finck "cp856", "cp856", "cp856" },
279c2c66affSColin Finck { "Hebrew (DOS)",
280c2c66affSColin Finck 862, MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT |
281c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
282c2c66affSColin Finck MIMECONTF_MIME_LATEST,
283c2c66affSColin Finck "dos-862", "dos-862", "dos-862" },
284c2c66affSColin Finck { "Hebrew (Windows)",
285c2c66affSColin Finck 1255, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
286c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
287c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
288c2c66affSColin Finck "windows-1255", "windows-1255", "windows-1255" },
289c2c66affSColin Finck { "Hebrew (ISO-Visual)",
290c2c66affSColin Finck 28598, MIMECONTF_BROWSER | MIMECONTF_MINIMAL | MIMECONTF_IMPORT |
291c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
292c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
293c2c66affSColin Finck "iso-8859-8", "iso-8859-8", "iso-8859-8" }
294c2c66affSColin Finck };
295c2c66affSColin Finck static const MIME_CP_INFO japanese_cp[] =
296c2c66affSColin Finck {
297c2c66affSColin Finck { "Japanese (Auto-Select)",
298c2c66affSColin Finck 50932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
299c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
300c2c66affSColin Finck MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
301c2c66affSColin Finck "_autodetect", "_autodetect", "_autodetect" },
302c2c66affSColin Finck { "Japanese (EUC)",
303c2c66affSColin Finck 51932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
304c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
305c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
306c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
307c2c66affSColin Finck "euc-jp", "euc-jp", "euc-jp" },
308c2c66affSColin Finck { "Japanese (JIS)",
309c2c66affSColin Finck 50220, MIMECONTF_IMPORT | MIMECONTF_MAILNEWS | MIMECONTF_EXPORT |
310c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID_NLS |
311c2c66affSColin Finck MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST |
312c2c66affSColin Finck MIMECONTF_MIME_IE4,
313c2c66affSColin Finck "iso-2022-jp","iso-2022-jp","iso-2022-jp"},
314c2c66affSColin Finck { "Japanese (JIS 0208-1990 and 0212-1990)",
315c2c66affSColin Finck 20932, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
316c2c66affSColin Finck MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST,
317c2c66affSColin Finck "EUC-JP","EUC-JP","EUC-JP"},
318c2c66affSColin Finck { "Japanese (JIS-Allow 1 byte Kana)",
319c2c66affSColin Finck 50221, MIMECONTF_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_SAVABLE_BROWSER |
320c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID_NLS |
321c2c66affSColin Finck MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST,
322c2c66affSColin Finck "csISO2022JP","iso-2022-jp","iso-2022-jp"},
323c2c66affSColin Finck { "Japanese (JIS-Allow 1 byte Kana - SO/SI)",
324c2c66affSColin Finck 50222, MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_VALID |
325c2c66affSColin Finck MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST,
326c2c66affSColin Finck "iso-2022-jp","iso-2022-jp","iso-2022-jp"},
327c2c66affSColin Finck { "Japanese (Mac)",
328c2c66affSColin Finck 10001, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
329c2c66affSColin Finck MIMECONTF_VALID | MIMECONTF_PRIVCONVERTER | MIMECONTF_MIME_LATEST,
330c2c66affSColin Finck "x-mac-japanese","x-mac-japanese","x-mac-japanese"},
331c2c66affSColin Finck { "Japanese (Shift-JIS)",
332c2c66affSColin Finck 932, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
333c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
334c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
335c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
336c2c66affSColin Finck "shift_jis", "iso-2022-jp", "iso-2022-jp" }
337c2c66affSColin Finck };
338c2c66affSColin Finck static const MIME_CP_INFO korean_cp[] =
339c2c66affSColin Finck {
340c2c66affSColin Finck { "Korean",
341c2c66affSColin Finck 949, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
342c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
343c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID_NLS |
344c2c66affSColin Finck MIMECONTF_MIME_LATEST,
345c2c66affSColin Finck "ks_c_5601-1987", "ks_c_5601-1987", "ks_c_5601-1987" }
346c2c66affSColin Finck };
347c2c66affSColin Finck static const MIME_CP_INFO thai_cp[] =
348c2c66affSColin Finck {
349c2c66affSColin Finck { "Thai (Windows)",
350c2c66affSColin Finck 874, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_MIME_LATEST,
351c2c66affSColin Finck "ibm-thai", "ibm-thai", "ibm-thai" }
352c2c66affSColin Finck };
353c2c66affSColin Finck static const MIME_CP_INFO turkish_cp[] =
354c2c66affSColin Finck {
355c2c66affSColin Finck { "Turkish (DOS)",
356c2c66affSColin Finck 857, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
357c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
358c2c66affSColin Finck "ibm857", "ibm857", "ibm857" },
359c2c66affSColin Finck { "IBM EBCDIC (Turkish Latin-5)",
360c2c66affSColin Finck 1026, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
361c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
362c2c66affSColin Finck "ibm1026", "ibm1026", "ibm1026" },
363c2c66affSColin Finck { "Turkish (Windows)",
364c2c66affSColin Finck 1254, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
365c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
366c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
367c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
368c2c66affSColin Finck "windows-1254", "windows-1254", "windows-1254" },
369c2c66affSColin Finck { "Turkish (Mac)",
370c2c66affSColin Finck 10081, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
371c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
372c2c66affSColin Finck "x-mac-turkish", "x-mac-turkish", "x-mac-turkish" },
373c2c66affSColin Finck { "Latin 3 (ISO)",
374c2c66affSColin Finck 28593, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT |
375c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_VALID |
376c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
377c2c66affSColin Finck "iso-8859-3", "iso-8859-3", "iso-8859-3" },
378c2c66affSColin Finck { "Turkish (ISO)",
379c2c66affSColin Finck 28599, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
380c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
381c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
382c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
383c2c66affSColin Finck "iso-8859-9", "iso-8859-9", "iso-8859-9" }
384c2c66affSColin Finck };
385c2c66affSColin Finck static const MIME_CP_INFO vietnamese_cp[] =
386c2c66affSColin Finck {
387c2c66affSColin Finck { "Vietnamese (Windows)",
388c2c66affSColin Finck 1258, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
389c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
390c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
391c2c66affSColin Finck MIMECONTF_MIME_LATEST,
392c2c66affSColin Finck "windows-1258", "windows-1258", "windows-1258" }
393c2c66affSColin Finck };
394c2c66affSColin Finck
395c2c66affSColin Finck static const WCHAR asciiW[] = {'a','s','c','i','i',0};
396c2c66affSColin Finck
397c2c66affSColin Finck static const MIME_CP_INFO western_cp[] =
398c2c66affSColin Finck {
399c2c66affSColin Finck { "IBM EBCDIC (US-Canada)",
400c2c66affSColin Finck 37, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
401c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
402c2c66affSColin Finck "ibm037", "ibm037", "ibm037" },
403c2c66affSColin Finck { "OEM United States",
404c2c66affSColin Finck 437, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
405c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
406c2c66affSColin Finck "ibm437", "ibm437", "ibm437" },
407c2c66affSColin Finck { "IBM EBCDIC (International)",
408c2c66affSColin Finck 500, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
409c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
410c2c66affSColin Finck "ibm500", "ibm500", "ibm500" },
411c2c66affSColin Finck { "Western European (DOS)",
412c2c66affSColin Finck 850, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
413c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
414c2c66affSColin Finck "ibm850", "ibm850", "ibm850" },
415c2c66affSColin Finck { "Portuguese (DOS)",
416c2c66affSColin Finck 860, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
417c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
418c2c66affSColin Finck "ibm860", "ibm860", "ibm860" },
419c2c66affSColin Finck { "Icelandic (DOS)",
420c2c66affSColin Finck 861, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
421c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
422c2c66affSColin Finck "ibm861", "ibm861", "ibm861" },
423c2c66affSColin Finck { "French Canadian (DOS)",
424c2c66affSColin Finck 863, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
425c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
426c2c66affSColin Finck "ibm863", "ibm863", "ibm863" },
427c2c66affSColin Finck { "Nordic (DOS)",
428c2c66affSColin Finck 865, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
429c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
430c2c66affSColin Finck "ibm865", "ibm865", "ibm865" },
431c2c66affSColin Finck { "Western European (Windows)",
432c2c66affSColin Finck 1252, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_MINIMAL |
433c2c66affSColin Finck MIMECONTF_IMPORT | MIMECONTF_SAVABLE_MAILNEWS |
434c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT | MIMECONTF_VALID |
435c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
436c2c66affSColin Finck "windows-1252", "windows-1252", "iso-8859-1" },
437c2c66affSColin Finck { "Western European (Mac)",
438c2c66affSColin Finck 10000, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
439c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
440c2c66affSColin Finck "macintosh", "macintosh", "macintosh" },
441c2c66affSColin Finck { "Icelandic (Mac)",
442c2c66affSColin Finck 10079, MIMECONTF_IMPORT | MIMECONTF_EXPORT | MIMECONTF_VALID |
443c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
444c2c66affSColin Finck "x-mac-icelandic", "x-mac-icelandic", "x-mac-icelandic" },
445c2c66affSColin Finck { "US-ASCII",
446c2c66affSColin Finck 20127, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT | MIMECONTF_EXPORT |
447c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_VALID |
448c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_LATEST,
449c2c66affSColin Finck "us-ascii", "us-ascii", "us-ascii", asciiW },
450c2c66affSColin Finck { "Western European (ISO)",
451c2c66affSColin Finck 28591, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
452c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
453c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
454c2c66affSColin Finck MIMECONTF_MIME_LATEST,
455c2c66affSColin Finck "iso-8859-1", "iso-8859-1", "iso-8859-1" },
456c2c66affSColin Finck { "Latin 9 (ISO)",
457c2c66affSColin Finck 28605, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT |
458c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
459c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
460c2c66affSColin Finck MIMECONTF_MIME_LATEST,
461c2c66affSColin Finck "iso-8859-15", "iso-8859-15", "iso-8859-15" }
462c2c66affSColin Finck };
463c2c66affSColin Finck static const MIME_CP_INFO unicode_cp[] =
464c2c66affSColin Finck {
465c2c66affSColin Finck { "Unicode",
466c2c66affSColin Finck CP_UNICODE, MIMECONTF_MINIMAL | MIMECONTF_IMPORT |
467c2c66affSColin Finck MIMECONTF_SAVABLE_BROWSER | MIMECONTF_EXPORT |
468c2c66affSColin Finck MIMECONTF_VALID | MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 |
469c2c66affSColin Finck MIMECONTF_MIME_LATEST,
470c2c66affSColin Finck "unicode", "unicode", "unicode" },
471c2c66affSColin Finck { "Unicode (UTF-7)",
472c2c66affSColin Finck CP_UTF7, MIMECONTF_MAILNEWS | MIMECONTF_IMPORT |
473c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_EXPORT | MIMECONTF_VALID |
474c2c66affSColin Finck MIMECONTF_VALID_NLS | MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
475c2c66affSColin Finck "utf-7", "utf-7", "utf-7" },
476c2c66affSColin Finck { "Unicode (UTF-8)",
477c2c66affSColin Finck CP_UTF8, MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_IMPORT |
478c2c66affSColin Finck MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER |
479c2c66affSColin Finck MIMECONTF_EXPORT | MIMECONTF_VALID | MIMECONTF_VALID_NLS |
480c2c66affSColin Finck MIMECONTF_MIME_IE4 | MIMECONTF_MIME_LATEST,
481c2c66affSColin Finck "utf-8", "utf-8", "utf-8" }
482c2c66affSColin Finck };
483c2c66affSColin Finck
484c2c66affSColin Finck static const struct mlang_data
485c2c66affSColin Finck {
486c2c66affSColin Finck const char *description;
487c2c66affSColin Finck UINT family_codepage;
488c2c66affSColin Finck UINT number_of_cp;
489c2c66affSColin Finck const MIME_CP_INFO *mime_cp_info;
490c2c66affSColin Finck const char *fixed_font;
491c2c66affSColin Finck const char *proportional_font;
492c2c66affSColin Finck SCRIPT_ID sid;
493c2c66affSColin Finck } mlang_data[] =
494c2c66affSColin Finck {
495ccc3eeaeSAmine Khaldi { "Arabic", 1256, ARRAY_SIZE(arabic_cp), arabic_cp,
4965e2c163fSAmine Khaldi "Simplified Arabic Fixed","Simplified Arabic", sidArabic },
497ccc3eeaeSAmine Khaldi { "Baltic", 1257, ARRAY_SIZE(baltic_cp), baltic_cp,
4985e2c163fSAmine Khaldi "Courier New","Arial", sidAsciiLatin },
499ccc3eeaeSAmine Khaldi { "Chinese Simplified", 936, ARRAY_SIZE(chinese_simplified_cp), chinese_simplified_cp,
5005e2c163fSAmine Khaldi "Simsun","Simsun", sidHan },
501ccc3eeaeSAmine Khaldi { "Chinese Traditional", 950, ARRAY_SIZE(chinese_traditional_cp), chinese_traditional_cp,
5025e2c163fSAmine Khaldi "MingLiu","New MingLiu", sidBopomofo },
503ccc3eeaeSAmine Khaldi { "Central European", 1250, ARRAY_SIZE(central_european_cp), central_european_cp,
5045e2c163fSAmine Khaldi "Courier New","Arial", sidAsciiLatin },
505ccc3eeaeSAmine Khaldi { "Cyrillic", 1251, ARRAY_SIZE(cyrillic_cp), cyrillic_cp,
5065e2c163fSAmine Khaldi "Courier New","Arial", sidCyrillic },
507ccc3eeaeSAmine Khaldi { "Greek", 1253, ARRAY_SIZE(greek_cp), greek_cp,
5085e2c163fSAmine Khaldi "Courier New","Arial", sidGreek },
509ccc3eeaeSAmine Khaldi { "Hebrew", 1255, ARRAY_SIZE(hebrew_cp), hebrew_cp,
5105e2c163fSAmine Khaldi "Miriam Fixed","David", sidHebrew },
511ccc3eeaeSAmine Khaldi { "Japanese", 932, ARRAY_SIZE(japanese_cp), japanese_cp,
512c2c66affSColin Finck "MS Gothic","MS PGothic", sidKana },
513ccc3eeaeSAmine Khaldi { "Korean", 949, ARRAY_SIZE(korean_cp), korean_cp,
5145e2c163fSAmine Khaldi "GulimChe","Gulim", sidHangul },
515ccc3eeaeSAmine Khaldi { "Thai", 874, ARRAY_SIZE(thai_cp), thai_cp,
5165e2c163fSAmine Khaldi "Tahoma","Tahoma", sidThai },
517ccc3eeaeSAmine Khaldi { "Turkish", 1254, ARRAY_SIZE(turkish_cp), turkish_cp,
5185e2c163fSAmine Khaldi "Courier New","Arial", sidAsciiLatin },
519ccc3eeaeSAmine Khaldi { "Vietnamese", 1258, ARRAY_SIZE(vietnamese_cp), vietnamese_cp,
5205e2c163fSAmine Khaldi "Courier New","Arial", sidAsciiLatin },
521ccc3eeaeSAmine Khaldi { "Western European", 1252, ARRAY_SIZE(western_cp), western_cp,
5225e2c163fSAmine Khaldi "Courier New","Arial", sidAsciiLatin },
523ccc3eeaeSAmine Khaldi { "Unicode", CP_UNICODE, ARRAY_SIZE(unicode_cp), unicode_cp,
5245e2c163fSAmine Khaldi "Courier New","Arial" }
525c2c66affSColin Finck };
526c2c66affSColin Finck
5275e2c163fSAmine Khaldi struct font_list
5285e2c163fSAmine Khaldi {
5295e2c163fSAmine Khaldi struct list list_entry;
5305e2c163fSAmine Khaldi HFONT base_font;
5315e2c163fSAmine Khaldi HFONT font;
5325e2c163fSAmine Khaldi UINT charset;
5335e2c163fSAmine Khaldi };
5345e2c163fSAmine Khaldi
5355e2c163fSAmine Khaldi static struct list font_cache = LIST_INIT(font_cache);
5365e2c163fSAmine Khaldi static CRITICAL_SECTION font_cache_critical;
5375e2c163fSAmine Khaldi static CRITICAL_SECTION_DEBUG font_cache_critical_debug =
5385e2c163fSAmine Khaldi {
5395e2c163fSAmine Khaldi 0, 0, &font_cache_critical,
5405e2c163fSAmine Khaldi { &font_cache_critical_debug.ProcessLocksList, &font_cache_critical_debug.ProcessLocksList },
5415e2c163fSAmine Khaldi 0, 0, { (DWORD_PTR)(__FILE__ ": font_cache_critical") }
5425e2c163fSAmine Khaldi };
5435e2c163fSAmine Khaldi static CRITICAL_SECTION font_cache_critical = { &font_cache_critical_debug, -1, 0, 0, 0, 0 };
5445e2c163fSAmine Khaldi
545c2c66affSColin Finck static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info);
546c2c66affSColin Finck
547c2c66affSColin Finck static LONG dll_count;
548c2c66affSColin Finck
549c2c66affSColin Finck /*
550c2c66affSColin Finck * Japanese Detection and Conversion Functions
551c2c66affSColin Finck */
552c2c66affSColin Finck
553c2c66affSColin Finck #define HANKATA(A) ((A >= 161) && (A <= 223))
554c2c66affSColin Finck #define ISEUC(A) ((A >= 161) && (A <= 254))
555c2c66affSColin Finck #define NOTEUC(A,B) (((A >= 129) && (A <= 159)) && ((B >= 64) && (B <= 160)))
556c2c66affSColin Finck #define SJIS1(A) (((A >= 129) && (A <= 159)) || ((A >= 224) && (A <= 239)))
557c2c66affSColin Finck #define SJIS2(A) ((A >= 64) && (A <= 252))
558c2c66affSColin Finck #define ISMARU(A) ((A >= 202) && (A <= 206))
559c2c66affSColin Finck #define ISNIGORI(A) (((A >= 182) && (A <= 196)) || ((A >= 202) && (A <= 206)))
560c2c66affSColin Finck
DetectJapaneseCode(LPCSTR input,DWORD count)561c2c66affSColin Finck static UINT DetectJapaneseCode(LPCSTR input, DWORD count)
562c2c66affSColin Finck {
563c2c66affSColin Finck UINT code = 0;
564c2c66affSColin Finck DWORD i = 0;
565c2c66affSColin Finck unsigned char c1,c2;
566c2c66affSColin Finck
567c2c66affSColin Finck while ((code == 0 || code == 51932) && i < count)
568c2c66affSColin Finck {
569c2c66affSColin Finck c1 = input[i];
570c2c66affSColin Finck if (c1 == 0x1b /* ESC */)
571c2c66affSColin Finck {
572c2c66affSColin Finck i++;
573c2c66affSColin Finck if (i >= count)
574c2c66affSColin Finck return code;
575c2c66affSColin Finck c1 = input[i];
576c2c66affSColin Finck if (c1 == '$')
577c2c66affSColin Finck {
578c2c66affSColin Finck i++;
579c2c66affSColin Finck if (i >= count)
580c2c66affSColin Finck return code;
581c2c66affSColin Finck c1 = input[i];
582c2c66affSColin Finck if (c1 =='B' || c1 == '@')
583c2c66affSColin Finck code = 50220;
584c2c66affSColin Finck }
585c2c66affSColin Finck if (c1 == 'K')
586c2c66affSColin Finck code = 50220;
587c2c66affSColin Finck }
588c2c66affSColin Finck else if (c1 >= 129)
589c2c66affSColin Finck {
590c2c66affSColin Finck i++;
591c2c66affSColin Finck if (i >= count)
592c2c66affSColin Finck return code;
593c2c66affSColin Finck c2 = input[i];
594c2c66affSColin Finck if NOTEUC(c1,c2)
595c2c66affSColin Finck code = 932;
596c2c66affSColin Finck else if (ISEUC(c1) && ISEUC(c2))
597c2c66affSColin Finck code = 51932;
598c2c66affSColin Finck else if (((c1 == 142)) && HANKATA(c2))
599c2c66affSColin Finck code = 51932;
600c2c66affSColin Finck }
601c2c66affSColin Finck i++;
602c2c66affSColin Finck }
603c2c66affSColin Finck return code;
604c2c66affSColin Finck }
605c2c66affSColin Finck
jis2sjis(unsigned char * p1,unsigned char * p2)606c2c66affSColin Finck static inline void jis2sjis(unsigned char *p1, unsigned char *p2)
607c2c66affSColin Finck {
608c2c66affSColin Finck unsigned char c1 = *p1;
609c2c66affSColin Finck unsigned char c2 = *p2;
610c2c66affSColin Finck int row = c1 < 95 ? 112 : 176;
611c2c66affSColin Finck int cell = c1 % 2 ? 31 + (c2 > 95) : 126;
612c2c66affSColin Finck
613c2c66affSColin Finck *p1 = ((c1 + 1) >> 1) + row;
614c2c66affSColin Finck *p2 = c2 + cell;
615c2c66affSColin Finck }
616c2c66affSColin Finck
sjis2jis(unsigned char * p1,unsigned char * p2)617c2c66affSColin Finck static inline void sjis2jis(unsigned char *p1, unsigned char *p2)
618c2c66affSColin Finck {
619c2c66affSColin Finck unsigned char c1 = *p1;
620c2c66affSColin Finck unsigned char c2 = *p2;
621c2c66affSColin Finck int shift = c2 < 159;
622c2c66affSColin Finck int row = c1 < 160 ? 112 : 176;
623c2c66affSColin Finck int cell = shift ? (31 + (c2 > 127)): 126;
624c2c66affSColin Finck
625c2c66affSColin Finck *p1 = ((c1 - row) << 1) - shift;
626c2c66affSColin Finck *p2 -= cell;
627c2c66affSColin Finck }
628c2c66affSColin Finck
han2zen(unsigned char * p1,unsigned char * p2)629c2c66affSColin Finck static int han2zen(unsigned char *p1, unsigned char *p2)
630c2c66affSColin Finck {
631c2c66affSColin Finck BOOL maru = FALSE;
632c2c66affSColin Finck BOOL nigori = FALSE;
633c2c66affSColin Finck static const unsigned char char1[] = {129,129,129,129,129,131,131,131,131,
634c2c66affSColin Finck 131,131,131,131,131,131,129,131,131,131,131,131,131,131,131,131,131,
635c2c66affSColin Finck 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
636c2c66affSColin Finck 131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
637c2c66affSColin Finck 131,129,129 };
638c2c66affSColin Finck static const unsigned char char2[] = {66,117,118,65,69,146,64,66,68,70,
639c2c66affSColin Finck 72,131,133,135,98,91,65,67,69,71,73,74,76,78,80,82,84,86,88,90,92,94,
640c2c66affSColin Finck 96,99,101,103,105,106,107,108,109,110,113,116,119,122,125,126,128,
641c2c66affSColin Finck 129,130,132,134,136,137,138,139,140,141,143,147,74,75};
642c2c66affSColin Finck
643c2c66affSColin Finck if (( *p2 == 222) && ((ISNIGORI(*p1) || (*p1 == 179))))
644c2c66affSColin Finck nigori = TRUE;
645c2c66affSColin Finck else if ((*p2 == 223) && (ISMARU(*p1)))
646c2c66affSColin Finck maru = TRUE;
647c2c66affSColin Finck
648c2c66affSColin Finck if (*p1 >= 161 && *p1 <= 223)
649c2c66affSColin Finck {
650c2c66affSColin Finck unsigned char index = *p1 - 161;
651c2c66affSColin Finck *p1 = char1[index];
652c2c66affSColin Finck *p2 = char2[index];
653c2c66affSColin Finck }
654c2c66affSColin Finck
655c2c66affSColin Finck if (maru || nigori)
656c2c66affSColin Finck {
657c2c66affSColin Finck if (nigori)
658c2c66affSColin Finck {
659c2c66affSColin Finck if (((*p2 >= 74) && (*p2 <= 103)) || ((*p2 >= 110) && (*p2 <= 122)))
660c2c66affSColin Finck (*p2)++;
661c2c66affSColin Finck else if ((*p1 == 131) && (*p2 == 69))
662c2c66affSColin Finck *p2 = 148;
663c2c66affSColin Finck }
664c2c66affSColin Finck else if ((maru) && ((*p2 >= 110) && (*p2 <= 122)))
665c2c66affSColin Finck *p2+= 2;
666c2c66affSColin Finck
667c2c66affSColin Finck return 1;
668c2c66affSColin Finck }
669c2c66affSColin Finck
670c2c66affSColin Finck return 0;
671c2c66affSColin Finck }
672c2c66affSColin Finck
673c2c66affSColin Finck
ConvertJIS2SJIS(LPCSTR input,DWORD count,LPSTR output)674c2c66affSColin Finck static UINT ConvertJIS2SJIS(LPCSTR input, DWORD count, LPSTR output)
675c2c66affSColin Finck {
676c2c66affSColin Finck DWORD i = 0;
677c2c66affSColin Finck int j = 0;
678c2c66affSColin Finck unsigned char p2,p;
679c2c66affSColin Finck BOOL shifted = FALSE;
680c2c66affSColin Finck
681c2c66affSColin Finck while (i < count)
682c2c66affSColin Finck {
683c2c66affSColin Finck p = input[i];
684c2c66affSColin Finck if (p == 0x1b /* ESC */)
685c2c66affSColin Finck {
686c2c66affSColin Finck i++;
687c2c66affSColin Finck if (i >= count)
688c2c66affSColin Finck return 0;
689c2c66affSColin Finck p2 = input[i];
690c2c66affSColin Finck if (p2 == '$' || p2 =='(')
691c2c66affSColin Finck i++;
692c2c66affSColin Finck if (p2 == 'K' || p2 =='$')
693c2c66affSColin Finck shifted = TRUE;
694c2c66affSColin Finck else
695c2c66affSColin Finck shifted = FALSE;
696c2c66affSColin Finck }
697c2c66affSColin Finck else
698c2c66affSColin Finck {
699c2c66affSColin Finck if (shifted)
700c2c66affSColin Finck {
701c2c66affSColin Finck i++;
702c2c66affSColin Finck if (i >= count)
703c2c66affSColin Finck return 0;
704c2c66affSColin Finck p2 = input[i];
705c2c66affSColin Finck jis2sjis(&p,&p2);
706c2c66affSColin Finck output[j++]=p;
707c2c66affSColin Finck output[j++]=p2;
708c2c66affSColin Finck }
709c2c66affSColin Finck else
710c2c66affSColin Finck {
711c2c66affSColin Finck output[j++] = p;
712c2c66affSColin Finck }
713c2c66affSColin Finck }
714c2c66affSColin Finck i++;
715c2c66affSColin Finck }
716c2c66affSColin Finck return j;
717c2c66affSColin Finck }
718c2c66affSColin Finck
exit_shift(LPSTR out,int c)719c2c66affSColin Finck static inline int exit_shift(LPSTR out, int c)
720c2c66affSColin Finck {
721c2c66affSColin Finck if (out)
722c2c66affSColin Finck {
723c2c66affSColin Finck out[c] = 0x1b;
724c2c66affSColin Finck out[c+1] = '(';
725c2c66affSColin Finck out[c+2] = 'B';
726c2c66affSColin Finck }
727c2c66affSColin Finck return 3;
728c2c66affSColin Finck }
729c2c66affSColin Finck
enter_shift(LPSTR out,int c)730c2c66affSColin Finck static inline int enter_shift(LPSTR out, int c)
731c2c66affSColin Finck {
732c2c66affSColin Finck if (out)
733c2c66affSColin Finck {
734c2c66affSColin Finck out[c] = 0x1b;
735c2c66affSColin Finck out[c+1] = '$';
736c2c66affSColin Finck out[c+2] = 'B';
737c2c66affSColin Finck }
738c2c66affSColin Finck return 3;
739c2c66affSColin Finck }
740c2c66affSColin Finck
741c2c66affSColin Finck
ConvertSJIS2JIS(LPCSTR input,DWORD count,LPSTR output)742c2c66affSColin Finck static UINT ConvertSJIS2JIS(LPCSTR input, DWORD count, LPSTR output)
743c2c66affSColin Finck {
744c2c66affSColin Finck DWORD i = 0;
745c2c66affSColin Finck int j = 0;
746c2c66affSColin Finck unsigned char p2,p;
747c2c66affSColin Finck BOOL shifted = FALSE;
748c2c66affSColin Finck
749c2c66affSColin Finck while (i < count)
750c2c66affSColin Finck {
751c2c66affSColin Finck p = input[i] & 0xff;
752c2c66affSColin Finck if (p == 10 || p == 13) /* NL and CR */
753c2c66affSColin Finck {
754c2c66affSColin Finck if (shifted)
755c2c66affSColin Finck {
756c2c66affSColin Finck shifted = FALSE;
757c2c66affSColin Finck j += exit_shift(output,j);
758c2c66affSColin Finck }
759c2c66affSColin Finck if (output)
760c2c66affSColin Finck output[j++] = p;
761c2c66affSColin Finck else
762c2c66affSColin Finck j++;
763c2c66affSColin Finck }
764c2c66affSColin Finck else
765c2c66affSColin Finck {
766c2c66affSColin Finck if (SJIS1(p))
767c2c66affSColin Finck {
768c2c66affSColin Finck i++;
769c2c66affSColin Finck if (i >= count)
770c2c66affSColin Finck return 0;
771c2c66affSColin Finck p2 = input[i] & 0xff;
772c2c66affSColin Finck if (SJIS2(p2))
773c2c66affSColin Finck {
774c2c66affSColin Finck sjis2jis(&p,&p2);
775c2c66affSColin Finck if (!shifted)
776c2c66affSColin Finck {
777c2c66affSColin Finck shifted = TRUE;
778c2c66affSColin Finck j+=enter_shift(output,j);
779c2c66affSColin Finck }
780c2c66affSColin Finck }
781c2c66affSColin Finck
782c2c66affSColin Finck if (output)
783c2c66affSColin Finck {
784c2c66affSColin Finck output[j++]=p;
785c2c66affSColin Finck output[j++]=p2;
786c2c66affSColin Finck }
787c2c66affSColin Finck else
788c2c66affSColin Finck j+=2;
789c2c66affSColin Finck }
790c2c66affSColin Finck else
791c2c66affSColin Finck {
792c2c66affSColin Finck if (HANKATA(p))
793c2c66affSColin Finck {
794c2c66affSColin Finck if ((i+1) >= count)
795c2c66affSColin Finck return 0;
796c2c66affSColin Finck p2 = input[i+1] & 0xff;
797c2c66affSColin Finck i+=han2zen(&p,&p2);
798c2c66affSColin Finck sjis2jis(&p,&p2);
799c2c66affSColin Finck if (!shifted)
800c2c66affSColin Finck {
801c2c66affSColin Finck shifted = TRUE;
802c2c66affSColin Finck j+=enter_shift(output,j);
803c2c66affSColin Finck }
804c2c66affSColin Finck if (output)
805c2c66affSColin Finck {
806c2c66affSColin Finck output[j++]=p;
807c2c66affSColin Finck output[j++]=p2;
808c2c66affSColin Finck }
809c2c66affSColin Finck else
810c2c66affSColin Finck j+=2;
811c2c66affSColin Finck }
812c2c66affSColin Finck else
813c2c66affSColin Finck {
814c2c66affSColin Finck if (shifted)
815c2c66affSColin Finck {
816c2c66affSColin Finck shifted = FALSE;
817c2c66affSColin Finck j += exit_shift(output,j);
818c2c66affSColin Finck }
819c2c66affSColin Finck if (output)
820c2c66affSColin Finck output[j++]=p;
821c2c66affSColin Finck else
822c2c66affSColin Finck j++;
823c2c66affSColin Finck }
824c2c66affSColin Finck }
825c2c66affSColin Finck }
826c2c66affSColin Finck i++;
827c2c66affSColin Finck }
828c2c66affSColin Finck if (shifted)
829c2c66affSColin Finck j += exit_shift(output,j);
830c2c66affSColin Finck return j;
831c2c66affSColin Finck }
832c2c66affSColin Finck
ConvertJISJapaneseToUnicode(LPCSTR input,DWORD count,LPWSTR output,DWORD out_count)833c2c66affSColin Finck static UINT ConvertJISJapaneseToUnicode(LPCSTR input, DWORD count,
834c2c66affSColin Finck LPWSTR output, DWORD out_count)
835c2c66affSColin Finck {
836c2c66affSColin Finck CHAR *sjis_string;
837c2c66affSColin Finck UINT rc = 0;
838c2c66affSColin Finck sjis_string = HeapAlloc(GetProcessHeap(),0,count);
839c2c66affSColin Finck rc = ConvertJIS2SJIS(input,count,sjis_string);
840c2c66affSColin Finck if (rc)
841c2c66affSColin Finck {
842c2c66affSColin Finck TRACE("%s\n",debugstr_an(sjis_string,rc));
843c2c66affSColin Finck if (output)
844c2c66affSColin Finck rc = MultiByteToWideChar(932,0,sjis_string,rc,output,out_count);
845c2c66affSColin Finck else
846c2c66affSColin Finck rc = MultiByteToWideChar(932,0,sjis_string,rc,0,0);
847c2c66affSColin Finck }
848c2c66affSColin Finck HeapFree(GetProcessHeap(),0,sjis_string);
849c2c66affSColin Finck return rc;
850c2c66affSColin Finck
851c2c66affSColin Finck }
852c2c66affSColin Finck
ConvertUnknownJapaneseToUnicode(LPCSTR input,DWORD count,LPWSTR output,DWORD out_count)853c2c66affSColin Finck static UINT ConvertUnknownJapaneseToUnicode(LPCSTR input, DWORD count,
854c2c66affSColin Finck LPWSTR output, DWORD out_count)
855c2c66affSColin Finck {
856c2c66affSColin Finck CHAR *sjis_string;
857c2c66affSColin Finck UINT rc = 0;
858c2c66affSColin Finck int code = DetectJapaneseCode(input,count);
859c2c66affSColin Finck TRACE("Japanese code %i\n",code);
860c2c66affSColin Finck
861c2c66affSColin Finck switch (code)
862c2c66affSColin Finck {
863c2c66affSColin Finck case 0:
864c2c66affSColin Finck if (output)
865c2c66affSColin Finck rc = MultiByteToWideChar(CP_ACP,0,input,count,output,out_count);
866c2c66affSColin Finck else
867c2c66affSColin Finck rc = MultiByteToWideChar(CP_ACP,0,input,count,0,0);
868c2c66affSColin Finck break;
869c2c66affSColin Finck
870c2c66affSColin Finck case 932:
871c2c66affSColin Finck if (output)
872c2c66affSColin Finck rc = MultiByteToWideChar(932,0,input,count,output,out_count);
873c2c66affSColin Finck else
874c2c66affSColin Finck rc = MultiByteToWideChar(932,0,input,count,0,0);
875c2c66affSColin Finck break;
876c2c66affSColin Finck
877c2c66affSColin Finck case 51932:
878c2c66affSColin Finck if (output)
879c2c66affSColin Finck rc = MultiByteToWideChar(20932,0,input,count,output,out_count);
880c2c66affSColin Finck else
881c2c66affSColin Finck rc = MultiByteToWideChar(20932,0,input,count,0,0);
882c2c66affSColin Finck break;
883c2c66affSColin Finck
884c2c66affSColin Finck case 50220:
885c2c66affSColin Finck sjis_string = HeapAlloc(GetProcessHeap(),0,count);
886c2c66affSColin Finck rc = ConvertJIS2SJIS(input,count,sjis_string);
887c2c66affSColin Finck if (rc)
888c2c66affSColin Finck {
889c2c66affSColin Finck TRACE("%s\n",debugstr_an(sjis_string,rc));
890c2c66affSColin Finck if (output)
891c2c66affSColin Finck rc = MultiByteToWideChar(932,0,sjis_string,rc,output,out_count);
892c2c66affSColin Finck else
893c2c66affSColin Finck rc = MultiByteToWideChar(932,0,sjis_string,rc,0,0);
894c2c66affSColin Finck }
895c2c66affSColin Finck HeapFree(GetProcessHeap(),0,sjis_string);
896c2c66affSColin Finck break;
897c2c66affSColin Finck }
898c2c66affSColin Finck return rc;
899c2c66affSColin Finck }
900c2c66affSColin Finck
ConvertJapaneseUnicodeToJIS(LPCWSTR input,DWORD count,LPSTR output,DWORD out_count)901c2c66affSColin Finck static UINT ConvertJapaneseUnicodeToJIS(LPCWSTR input, DWORD count,
902c2c66affSColin Finck LPSTR output, DWORD out_count)
903c2c66affSColin Finck {
904c2c66affSColin Finck CHAR *sjis_string;
905c2c66affSColin Finck INT len;
906c2c66affSColin Finck UINT rc = 0;
907c2c66affSColin Finck
908c2c66affSColin Finck len = WideCharToMultiByte(932,0,input,count,0,0,NULL,NULL);
909c2c66affSColin Finck sjis_string = HeapAlloc(GetProcessHeap(),0,len);
910c2c66affSColin Finck WideCharToMultiByte(932,0,input,count,sjis_string,len,NULL,NULL);
911c2c66affSColin Finck TRACE("%s\n",debugstr_an(sjis_string,len));
912c2c66affSColin Finck
913c2c66affSColin Finck rc = ConvertSJIS2JIS(sjis_string, len, NULL);
914c2c66affSColin Finck if (out_count >= rc)
915c2c66affSColin Finck {
916c2c66affSColin Finck ConvertSJIS2JIS(sjis_string, len, output);
917c2c66affSColin Finck }
918c2c66affSColin Finck HeapFree(GetProcessHeap(),0,sjis_string);
919c2c66affSColin Finck return rc;
920c2c66affSColin Finck
921c2c66affSColin Finck }
922c2c66affSColin Finck
923c2c66affSColin Finck /*
924c2c66affSColin Finck * Dll lifetime tracking declaration
925c2c66affSColin Finck */
LockModule(void)926c2c66affSColin Finck static void LockModule(void)
927c2c66affSColin Finck {
928c2c66affSColin Finck InterlockedIncrement(&dll_count);
929c2c66affSColin Finck }
930c2c66affSColin Finck
UnlockModule(void)931c2c66affSColin Finck static void UnlockModule(void)
932c2c66affSColin Finck {
933c2c66affSColin Finck InterlockedDecrement(&dll_count);
934c2c66affSColin Finck }
935c2c66affSColin Finck
DllMain(HINSTANCE hInstDLL,DWORD fdwReason,LPVOID lpv)936c2c66affSColin Finck BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
937c2c66affSColin Finck {
938c2c66affSColin Finck switch(fdwReason) {
939c2c66affSColin Finck case DLL_PROCESS_ATTACH:
940c2c66affSColin Finck instance = hInstDLL;
941c2c66affSColin Finck MLANG_tls_index = TlsAlloc();
942c2c66affSColin Finck DisableThreadLibraryCalls(hInstDLL);
943c2c66affSColin Finck break;
944c2c66affSColin Finck case DLL_PROCESS_DETACH:
945c2c66affSColin Finck if (lpv) break;
946c2c66affSColin Finck TlsFree(MLANG_tls_index);
947c2c66affSColin Finck break;
948c2c66affSColin Finck }
949c2c66affSColin Finck return TRUE;
950c2c66affSColin Finck }
951c2c66affSColin Finck
ConvertINetMultiByteToUnicode(LPDWORD pdwMode,DWORD dwEncoding,LPCSTR pSrcStr,LPINT pcSrcSize,LPWSTR pDstStr,LPINT pcDstSize)952c2c66affSColin Finck HRESULT WINAPI ConvertINetMultiByteToUnicode(
953c2c66affSColin Finck LPDWORD pdwMode,
954c2c66affSColin Finck DWORD dwEncoding,
955c2c66affSColin Finck LPCSTR pSrcStr,
956c2c66affSColin Finck LPINT pcSrcSize,
957c2c66affSColin Finck LPWSTR pDstStr,
958c2c66affSColin Finck LPINT pcDstSize)
959c2c66affSColin Finck {
960c2c66affSColin Finck INT src_len = -1;
961c2c66affSColin Finck
962c2c66affSColin Finck TRACE("%p %d %s %p %p %p\n", pdwMode, dwEncoding,
963c2c66affSColin Finck debugstr_a(pSrcStr), pcSrcSize, pDstStr, pcDstSize);
964c2c66affSColin Finck
965c2c66affSColin Finck if (!pcDstSize)
966c2c66affSColin Finck return E_FAIL;
967c2c66affSColin Finck
968c2c66affSColin Finck if (!pcSrcSize)
969c2c66affSColin Finck pcSrcSize = &src_len;
970c2c66affSColin Finck
971c2c66affSColin Finck if (!*pcSrcSize)
972c2c66affSColin Finck {
973c2c66affSColin Finck *pcDstSize = 0;
974c2c66affSColin Finck return S_OK;
975c2c66affSColin Finck }
976c2c66affSColin Finck
977c2c66affSColin Finck /* forwarding euc-jp to EUC-JP */
978c2c66affSColin Finck if (dwEncoding == 51932)
979c2c66affSColin Finck dwEncoding = 20932;
980c2c66affSColin Finck
981c2c66affSColin Finck switch (dwEncoding)
982c2c66affSColin Finck {
983c2c66affSColin Finck case CP_UNICODE:
984c2c66affSColin Finck if (*pcSrcSize == -1)
985c2c66affSColin Finck *pcSrcSize = lstrlenW((LPCWSTR)pSrcStr);
986c2c66affSColin Finck *pcDstSize = min(*pcSrcSize, *pcDstSize);
987c2c66affSColin Finck *pcSrcSize *= sizeof(WCHAR);
988c2c66affSColin Finck if (pDstStr)
989c2c66affSColin Finck memmove(pDstStr, pSrcStr, *pcDstSize * sizeof(WCHAR));
990c2c66affSColin Finck break;
991c2c66affSColin Finck
992c2c66affSColin Finck case 50220:
993c2c66affSColin Finck case 50221:
994c2c66affSColin Finck case 50222:
995c2c66affSColin Finck *pcDstSize = ConvertJISJapaneseToUnicode(pSrcStr,*pcSrcSize,pDstStr,*pcDstSize);
996c2c66affSColin Finck break;
997c2c66affSColin Finck case 50932:
998c2c66affSColin Finck *pcDstSize = ConvertUnknownJapaneseToUnicode(pSrcStr,*pcSrcSize,pDstStr,*pcDstSize);
999c2c66affSColin Finck break;
1000c2c66affSColin Finck
1001c2c66affSColin Finck default:
1002c2c66affSColin Finck if (*pcSrcSize == -1)
1003c2c66affSColin Finck *pcSrcSize = lstrlenA(pSrcStr);
1004c2c66affSColin Finck
1005c2c66affSColin Finck if (pDstStr)
1006c2c66affSColin Finck *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, pDstStr, *pcDstSize);
1007c2c66affSColin Finck else
1008c2c66affSColin Finck *pcDstSize = MultiByteToWideChar(dwEncoding, 0, pSrcStr, *pcSrcSize, NULL, 0);
1009c2c66affSColin Finck break;
1010c2c66affSColin Finck }
1011c2c66affSColin Finck
1012c2c66affSColin Finck if (!*pcDstSize)
1013c2c66affSColin Finck return E_FAIL;
1014c2c66affSColin Finck
1015c2c66affSColin Finck return S_OK;
1016c2c66affSColin Finck }
1017c2c66affSColin Finck
ConvertINetUnicodeToMultiByte(LPDWORD pdwMode,DWORD dwEncoding,LPCWSTR pSrcStr,LPINT pcSrcSize,LPSTR pDstStr,LPINT pcDstSize)1018c2c66affSColin Finck HRESULT WINAPI ConvertINetUnicodeToMultiByte(
1019c2c66affSColin Finck LPDWORD pdwMode,
1020c2c66affSColin Finck DWORD dwEncoding,
1021c2c66affSColin Finck LPCWSTR pSrcStr,
1022c2c66affSColin Finck LPINT pcSrcSize,
1023c2c66affSColin Finck LPSTR pDstStr,
1024c2c66affSColin Finck LPINT pcDstSize)
1025c2c66affSColin Finck {
1026c2c66affSColin Finck INT destsz, size;
1027c2c66affSColin Finck INT src_len = -1;
1028c2c66affSColin Finck
1029c2c66affSColin Finck TRACE("%p %d %s %p %p %p\n", pdwMode, dwEncoding,
1030c2c66affSColin Finck debugstr_w(pSrcStr), pcSrcSize, pDstStr, pcDstSize);
1031c2c66affSColin Finck
1032c2c66affSColin Finck if (!pcDstSize)
1033c2c66affSColin Finck return S_OK;
1034c2c66affSColin Finck
1035c2c66affSColin Finck if (!pcSrcSize)
1036c2c66affSColin Finck pcSrcSize = &src_len;
1037c2c66affSColin Finck
1038c2c66affSColin Finck destsz = (pDstStr) ? *pcDstSize : 0;
1039c2c66affSColin Finck *pcDstSize = 0;
1040c2c66affSColin Finck
1041c2c66affSColin Finck if (!pSrcStr || !*pcSrcSize)
1042c2c66affSColin Finck return S_OK;
1043c2c66affSColin Finck
1044c2c66affSColin Finck if (*pcSrcSize == -1)
1045c2c66affSColin Finck *pcSrcSize = lstrlenW(pSrcStr);
1046c2c66affSColin Finck
1047c2c66affSColin Finck /* forwarding euc-jp to EUC-JP */
1048c2c66affSColin Finck if (dwEncoding == 51932)
1049c2c66affSColin Finck dwEncoding = 20932;
1050c2c66affSColin Finck
1051c2c66affSColin Finck if (dwEncoding == CP_UNICODE)
1052c2c66affSColin Finck {
1053c2c66affSColin Finck if (*pcSrcSize == -1)
1054c2c66affSColin Finck *pcSrcSize = lstrlenW(pSrcStr);
1055c2c66affSColin Finck
1056c2c66affSColin Finck size = min(*pcSrcSize, destsz) * sizeof(WCHAR);
1057c2c66affSColin Finck if (pDstStr)
1058c2c66affSColin Finck memmove(pDstStr, pSrcStr, size);
1059c2c66affSColin Finck
1060c2c66affSColin Finck if (size >= destsz)
1061c2c66affSColin Finck goto fail;
1062c2c66affSColin Finck }
1063c2c66affSColin Finck else if (dwEncoding == 50220 || dwEncoding == 50221 || dwEncoding == 50222)
1064c2c66affSColin Finck {
1065c2c66affSColin Finck size = ConvertJapaneseUnicodeToJIS(pSrcStr, *pcSrcSize, NULL, 0);
1066c2c66affSColin Finck if (!size)
1067c2c66affSColin Finck goto fail;
1068c2c66affSColin Finck
1069c2c66affSColin Finck if (pDstStr)
1070c2c66affSColin Finck {
1071c2c66affSColin Finck size = ConvertJapaneseUnicodeToJIS(pSrcStr, *pcSrcSize, pDstStr,
1072c2c66affSColin Finck destsz);
1073c2c66affSColin Finck if (!size)
1074c2c66affSColin Finck goto fail;
1075c2c66affSColin Finck }
1076c2c66affSColin Finck
1077c2c66affSColin Finck }
1078c2c66affSColin Finck else
1079c2c66affSColin Finck {
1080c2c66affSColin Finck size = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize,
1081c2c66affSColin Finck NULL, 0, NULL, NULL);
1082c2c66affSColin Finck if (!size)
1083c2c66affSColin Finck goto fail;
1084c2c66affSColin Finck
1085c2c66affSColin Finck if (pDstStr)
1086c2c66affSColin Finck {
1087c2c66affSColin Finck size = WideCharToMultiByte(dwEncoding, 0, pSrcStr, *pcSrcSize,
1088c2c66affSColin Finck pDstStr, destsz, NULL, NULL);
1089c2c66affSColin Finck if (!size)
1090c2c66affSColin Finck goto fail;
1091c2c66affSColin Finck }
1092c2c66affSColin Finck }
1093c2c66affSColin Finck
1094c2c66affSColin Finck *pcDstSize = size;
1095c2c66affSColin Finck return S_OK;
1096c2c66affSColin Finck
1097c2c66affSColin Finck fail:
1098c2c66affSColin Finck *pcSrcSize = 0;
1099c2c66affSColin Finck *pcDstSize = 0;
1100c2c66affSColin Finck return E_FAIL;
1101c2c66affSColin Finck }
1102c2c66affSColin Finck
ConvertINetString(LPDWORD pdwMode,DWORD dwSrcEncoding,DWORD dwDstEncoding,LPCSTR pSrcStr,LPINT pcSrcSize,LPSTR pDstStr,LPINT pcDstSize)1103c2c66affSColin Finck HRESULT WINAPI ConvertINetString(
1104c2c66affSColin Finck LPDWORD pdwMode,
1105c2c66affSColin Finck DWORD dwSrcEncoding,
1106c2c66affSColin Finck DWORD dwDstEncoding,
1107c2c66affSColin Finck LPCSTR pSrcStr,
1108c2c66affSColin Finck LPINT pcSrcSize,
1109c2c66affSColin Finck LPSTR pDstStr,
1110c2c66affSColin Finck LPINT pcDstSize
1111c2c66affSColin Finck )
1112c2c66affSColin Finck {
1113c2c66affSColin Finck TRACE("%p %d %d %s %p %p %p\n", pdwMode, dwSrcEncoding, dwDstEncoding,
1114c2c66affSColin Finck debugstr_a(pSrcStr), pcSrcSize, pDstStr, pcDstSize);
1115c2c66affSColin Finck
1116c2c66affSColin Finck if (dwSrcEncoding == CP_UNICODE)
1117c2c66affSColin Finck {
1118c2c66affSColin Finck INT cSrcSizeW;
1119c2c66affSColin Finck if (pcSrcSize && *pcSrcSize != -1)
1120c2c66affSColin Finck {
1121c2c66affSColin Finck cSrcSizeW = *pcSrcSize / sizeof(WCHAR);
1122c2c66affSColin Finck pcSrcSize = &cSrcSizeW;
1123c2c66affSColin Finck }
1124c2c66affSColin Finck return ConvertINetUnicodeToMultiByte(pdwMode, dwDstEncoding, (LPCWSTR)pSrcStr, pcSrcSize, pDstStr, pcDstSize);
1125c2c66affSColin Finck }
1126c2c66affSColin Finck else if (dwDstEncoding == CP_UNICODE)
1127c2c66affSColin Finck {
1128c2c66affSColin Finck HRESULT hr = ConvertINetMultiByteToUnicode(pdwMode, dwSrcEncoding, pSrcStr, pcSrcSize, (LPWSTR)pDstStr, pcDstSize);
1129c2c66affSColin Finck *pcDstSize *= sizeof(WCHAR);
1130c2c66affSColin Finck return hr;
1131c2c66affSColin Finck }
1132c2c66affSColin Finck else
1133c2c66affSColin Finck {
1134c2c66affSColin Finck INT cDstSizeW;
1135c2c66affSColin Finck LPWSTR pDstStrW;
1136c2c66affSColin Finck HRESULT hr;
1137c2c66affSColin Finck
1138c2c66affSColin Finck TRACE("convert %s from %d to %d\n", debugstr_a(pSrcStr), dwSrcEncoding, dwDstEncoding);
1139c2c66affSColin Finck
1140c2c66affSColin Finck hr = ConvertINetMultiByteToUnicode(pdwMode, dwSrcEncoding, pSrcStr, pcSrcSize, NULL, &cDstSizeW);
1141c2c66affSColin Finck if (hr != S_OK)
1142c2c66affSColin Finck return hr;
1143c2c66affSColin Finck
1144c2c66affSColin Finck pDstStrW = HeapAlloc(GetProcessHeap(), 0, cDstSizeW * sizeof(WCHAR));
1145c2c66affSColin Finck hr = ConvertINetMultiByteToUnicode(pdwMode, dwSrcEncoding, pSrcStr, pcSrcSize, pDstStrW, &cDstSizeW);
1146c2c66affSColin Finck if (hr == S_OK)
1147c2c66affSColin Finck hr = ConvertINetUnicodeToMultiByte(pdwMode, dwDstEncoding, pDstStrW, &cDstSizeW, pDstStr, pcDstSize);
1148c2c66affSColin Finck
1149c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pDstStrW);
1150c2c66affSColin Finck return hr;
1151c2c66affSColin Finck }
1152c2c66affSColin Finck }
1153c2c66affSColin Finck
GetFamilyCodePage(UINT uiCodePage,UINT * puiFamilyCodePage)1154c2c66affSColin Finck static HRESULT GetFamilyCodePage(
1155c2c66affSColin Finck UINT uiCodePage,
1156c2c66affSColin Finck UINT* puiFamilyCodePage)
1157c2c66affSColin Finck {
1158c2c66affSColin Finck UINT i, n;
1159c2c66affSColin Finck
1160c2c66affSColin Finck TRACE("%u %p\n", uiCodePage, puiFamilyCodePage);
1161c2c66affSColin Finck
1162c2c66affSColin Finck if (!puiFamilyCodePage) return S_FALSE;
1163c2c66affSColin Finck
1164ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
1165c2c66affSColin Finck {
1166c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
1167c2c66affSColin Finck {
1168c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
1169c2c66affSColin Finck {
1170c2c66affSColin Finck *puiFamilyCodePage = mlang_data[i].family_codepage;
1171c2c66affSColin Finck return S_OK;
1172c2c66affSColin Finck }
1173c2c66affSColin Finck }
1174c2c66affSColin Finck }
1175c2c66affSColin Finck
1176c2c66affSColin Finck return S_FALSE;
1177c2c66affSColin Finck }
1178c2c66affSColin Finck
IsConvertINetStringAvailable(DWORD dwSrcEncoding,DWORD dwDstEncoding)1179c2c66affSColin Finck HRESULT WINAPI IsConvertINetStringAvailable(
1180c2c66affSColin Finck DWORD dwSrcEncoding,
1181c2c66affSColin Finck DWORD dwDstEncoding)
1182c2c66affSColin Finck {
1183c2c66affSColin Finck UINT src_family, dst_family;
1184c2c66affSColin Finck
1185c2c66affSColin Finck TRACE("%d %d\n", dwSrcEncoding, dwDstEncoding);
1186c2c66affSColin Finck
1187c2c66affSColin Finck if (GetFamilyCodePage(dwSrcEncoding, &src_family) != S_OK ||
1188c2c66affSColin Finck GetFamilyCodePage(dwDstEncoding, &dst_family) != S_OK)
1189c2c66affSColin Finck return S_FALSE;
1190c2c66affSColin Finck
1191c2c66affSColin Finck if (src_family == dst_family) return S_OK;
1192c2c66affSColin Finck
1193c2c66affSColin Finck /* we can convert any codepage to/from unicode */
1194c2c66affSColin Finck if (src_family == CP_UNICODE || dst_family == CP_UNICODE) return S_OK;
1195c2c66affSColin Finck
1196c2c66affSColin Finck return S_FALSE;
1197c2c66affSColin Finck }
1198c2c66affSColin Finck
lcid_to_rfc1766A(LCID lcid,LPSTR rfc1766,INT len)1199c2c66affSColin Finck static inline HRESULT lcid_to_rfc1766A( LCID lcid, LPSTR rfc1766, INT len )
1200c2c66affSColin Finck {
1201c2c66affSColin Finck CHAR buffer[MAX_RFC1766_NAME];
1202c2c66affSColin Finck INT n = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, buffer, MAX_RFC1766_NAME);
1203c2c66affSColin Finck INT i;
1204c2c66affSColin Finck
1205c2c66affSColin Finck if (n)
1206c2c66affSColin Finck {
1207c2c66affSColin Finck i = PRIMARYLANGID(lcid);
1208c2c66affSColin Finck if ((((i == LANG_ENGLISH) || (i == LANG_CHINESE) || (i == LANG_ARABIC)) &&
1209c2c66affSColin Finck (SUBLANGID(lcid) == SUBLANG_DEFAULT)) ||
1210c2c66affSColin Finck (SUBLANGID(lcid) > SUBLANG_DEFAULT)) {
1211c2c66affSColin Finck
1212c2c66affSColin Finck buffer[n - 1] = '-';
1213c2c66affSColin Finck i = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer + n, MAX_RFC1766_NAME - n);
1214c2c66affSColin Finck if (!i)
1215c2c66affSColin Finck buffer[n - 1] = '\0';
1216c2c66affSColin Finck }
1217c2c66affSColin Finck else
1218c2c66affSColin Finck i = 0;
1219c2c66affSColin Finck
1220c2c66affSColin Finck LCMapStringA( LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, buffer, n + i, rfc1766, len );
1221c2c66affSColin Finck return ((n + i) > len) ? E_INVALIDARG : S_OK;
1222c2c66affSColin Finck }
1223c2c66affSColin Finck return E_FAIL;
1224c2c66affSColin Finck }
1225c2c66affSColin Finck
lcid_to_rfc1766W(LCID lcid,LPWSTR rfc1766,INT len)1226c2c66affSColin Finck static inline HRESULT lcid_to_rfc1766W( LCID lcid, LPWSTR rfc1766, INT len )
1227c2c66affSColin Finck {
1228c2c66affSColin Finck WCHAR buffer[MAX_RFC1766_NAME];
1229c2c66affSColin Finck INT n = GetLocaleInfoW(lcid, LOCALE_SISO639LANGNAME, buffer, MAX_RFC1766_NAME);
1230c2c66affSColin Finck INT i;
1231c2c66affSColin Finck
1232c2c66affSColin Finck if (n)
1233c2c66affSColin Finck {
1234c2c66affSColin Finck i = PRIMARYLANGID(lcid);
1235c2c66affSColin Finck if ((((i == LANG_ENGLISH) || (i == LANG_CHINESE) || (i == LANG_ARABIC)) &&
1236c2c66affSColin Finck (SUBLANGID(lcid) == SUBLANG_DEFAULT)) ||
1237c2c66affSColin Finck (SUBLANGID(lcid) > SUBLANG_DEFAULT)) {
1238c2c66affSColin Finck
1239c2c66affSColin Finck buffer[n - 1] = '-';
1240c2c66affSColin Finck i = GetLocaleInfoW(lcid, LOCALE_SISO3166CTRYNAME, buffer + n, MAX_RFC1766_NAME - n);
1241c2c66affSColin Finck if (!i)
1242c2c66affSColin Finck buffer[n - 1] = '\0';
1243c2c66affSColin Finck }
1244c2c66affSColin Finck else
1245c2c66affSColin Finck i = 0;
1246c2c66affSColin Finck
1247c2c66affSColin Finck LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, buffer, n + i, rfc1766, len);
1248c2c66affSColin Finck return ((n + i) > len) ? E_INVALIDARG : S_OK;
1249c2c66affSColin Finck }
1250c2c66affSColin Finck return E_FAIL;
1251c2c66affSColin Finck }
1252c2c66affSColin Finck
LcidToRfc1766A(LCID lcid,LPSTR pszRfc1766,INT nChar)1253c2c66affSColin Finck HRESULT WINAPI LcidToRfc1766A(
1254c2c66affSColin Finck LCID lcid,
1255c2c66affSColin Finck LPSTR pszRfc1766,
1256c2c66affSColin Finck INT nChar)
1257c2c66affSColin Finck {
1258c2c66affSColin Finck TRACE("%04x %p %u\n", lcid, pszRfc1766, nChar);
1259c2c66affSColin Finck if (!pszRfc1766)
1260c2c66affSColin Finck return E_INVALIDARG;
1261c2c66affSColin Finck
1262c2c66affSColin Finck return lcid_to_rfc1766A(lcid, pszRfc1766, nChar);
1263c2c66affSColin Finck }
1264c2c66affSColin Finck
LcidToRfc1766W(LCID lcid,LPWSTR pszRfc1766,INT nChar)1265c2c66affSColin Finck HRESULT WINAPI LcidToRfc1766W(
1266c2c66affSColin Finck LCID lcid,
1267c2c66affSColin Finck LPWSTR pszRfc1766,
1268c2c66affSColin Finck INT nChar)
1269c2c66affSColin Finck {
1270c2c66affSColin Finck TRACE("%04x %p %u\n", lcid, pszRfc1766, nChar);
1271c2c66affSColin Finck if (!pszRfc1766)
1272c2c66affSColin Finck return E_INVALIDARG;
1273c2c66affSColin Finck
1274c2c66affSColin Finck return lcid_to_rfc1766W(lcid, pszRfc1766, nChar);
1275c2c66affSColin Finck }
1276c2c66affSColin Finck
lcid_from_rfc1766(IEnumRfc1766 * iface,LCID * lcid,LPCWSTR rfc1766)1277c2c66affSColin Finck static HRESULT lcid_from_rfc1766(IEnumRfc1766 *iface, LCID *lcid, LPCWSTR rfc1766)
1278c2c66affSColin Finck {
1279c2c66affSColin Finck RFC1766INFO info;
1280c2c66affSColin Finck ULONG num;
1281c2c66affSColin Finck
1282c2c66affSColin Finck while (IEnumRfc1766_Next(iface, 1, &info, &num) == S_OK)
1283c2c66affSColin Finck {
1284853d6414SAmine Khaldi if (!wcsicmp(info.wszRfc1766, rfc1766))
1285c2c66affSColin Finck {
1286c2c66affSColin Finck *lcid = info.lcid;
1287c2c66affSColin Finck return S_OK;
1288c2c66affSColin Finck }
1289853d6414SAmine Khaldi if (lstrlenW(rfc1766) == 2 && !memcmp(info.wszRfc1766, rfc1766, 2 * sizeof(WCHAR)))
1290c2c66affSColin Finck {
1291c2c66affSColin Finck *lcid = PRIMARYLANGID(info.lcid);
1292c2c66affSColin Finck return S_OK;
1293c2c66affSColin Finck }
1294c2c66affSColin Finck }
1295c2c66affSColin Finck
1296c2c66affSColin Finck return E_FAIL;
1297c2c66affSColin Finck }
1298c2c66affSColin Finck
Rfc1766ToLcidW(LCID * pLocale,LPCWSTR pszRfc1766)1299c2c66affSColin Finck HRESULT WINAPI Rfc1766ToLcidW(LCID *pLocale, LPCWSTR pszRfc1766)
1300c2c66affSColin Finck {
1301c2c66affSColin Finck IEnumRfc1766 *enumrfc1766;
1302c2c66affSColin Finck HRESULT hr;
1303c2c66affSColin Finck
1304c2c66affSColin Finck TRACE("(%p, %s)\n", pLocale, debugstr_w(pszRfc1766));
1305c2c66affSColin Finck
1306c2c66affSColin Finck if (!pLocale || !pszRfc1766)
1307c2c66affSColin Finck return E_INVALIDARG;
1308c2c66affSColin Finck
1309c2c66affSColin Finck hr = EnumRfc1766_create(0, &enumrfc1766);
1310c2c66affSColin Finck if (FAILED(hr))
1311c2c66affSColin Finck return hr;
1312c2c66affSColin Finck
1313c2c66affSColin Finck hr = lcid_from_rfc1766(enumrfc1766, pLocale, pszRfc1766);
1314c2c66affSColin Finck IEnumRfc1766_Release(enumrfc1766);
1315c2c66affSColin Finck
1316c2c66affSColin Finck return hr;
1317c2c66affSColin Finck }
1318c2c66affSColin Finck
Rfc1766ToLcidA(LCID * lcid,LPCSTR rfc1766A)1319c2c66affSColin Finck HRESULT WINAPI Rfc1766ToLcidA(LCID *lcid, LPCSTR rfc1766A)
1320c2c66affSColin Finck {
1321c2c66affSColin Finck WCHAR rfc1766W[MAX_RFC1766_NAME + 1];
1322c2c66affSColin Finck
1323c2c66affSColin Finck if (!rfc1766A)
1324c2c66affSColin Finck return E_INVALIDARG;
1325c2c66affSColin Finck
1326c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, rfc1766A, -1, rfc1766W, MAX_RFC1766_NAME);
1327c2c66affSColin Finck rfc1766W[MAX_RFC1766_NAME] = 0;
1328c2c66affSColin Finck
1329c2c66affSColin Finck return Rfc1766ToLcidW(lcid, rfc1766W);
1330c2c66affSColin Finck }
1331c2c66affSColin Finck
map_font(HDC hdc,DWORD codepages,HFONT src_font,HFONT * dst_font)13325e2c163fSAmine Khaldi static HRESULT map_font(HDC hdc, DWORD codepages, HFONT src_font, HFONT *dst_font)
13335e2c163fSAmine Khaldi {
13345e2c163fSAmine Khaldi struct font_list *font_list_entry;
13355e2c163fSAmine Khaldi CHARSETINFO charset_info;
13365e2c163fSAmine Khaldi HFONT new_font, old_font;
13375e2c163fSAmine Khaldi LOGFONTW font_attr;
13385e2c163fSAmine Khaldi DWORD mask, Csb[2];
13395e2c163fSAmine Khaldi BOOL found_cached;
13405e2c163fSAmine Khaldi UINT charset;
13415e2c163fSAmine Khaldi BOOL ret;
13425e2c163fSAmine Khaldi UINT i;
13435e2c163fSAmine Khaldi
13445e2c163fSAmine Khaldi if (hdc == NULL || src_font == NULL) return E_FAIL;
13455e2c163fSAmine Khaldi
13465e2c163fSAmine Khaldi for (i = 0; i < 32; i++)
13475e2c163fSAmine Khaldi {
13485e2c163fSAmine Khaldi mask = (DWORD)(1 << i);
13495e2c163fSAmine Khaldi if (codepages & mask)
13505e2c163fSAmine Khaldi {
13515e2c163fSAmine Khaldi Csb[0] = mask;
13525e2c163fSAmine Khaldi Csb[1] = 0x0;
13535e2c163fSAmine Khaldi ret = TranslateCharsetInfo(Csb, &charset_info, TCI_SRCFONTSIG);
13545e2c163fSAmine Khaldi if (!ret) continue;
13555e2c163fSAmine Khaldi
13565e2c163fSAmine Khaldi /* use cached font if possible */
13575e2c163fSAmine Khaldi found_cached = FALSE;
13585e2c163fSAmine Khaldi EnterCriticalSection(&font_cache_critical);
13595e2c163fSAmine Khaldi LIST_FOR_EACH_ENTRY(font_list_entry, &font_cache, struct font_list, list_entry)
13605e2c163fSAmine Khaldi {
13615e2c163fSAmine Khaldi if (font_list_entry->charset == charset_info.ciCharset &&
13625e2c163fSAmine Khaldi font_list_entry->base_font == src_font)
13635e2c163fSAmine Khaldi {
13645e2c163fSAmine Khaldi if (dst_font != NULL)
13655e2c163fSAmine Khaldi *dst_font = font_list_entry->font;
13665e2c163fSAmine Khaldi found_cached = TRUE;
13675e2c163fSAmine Khaldi }
13685e2c163fSAmine Khaldi }
13695e2c163fSAmine Khaldi LeaveCriticalSection(&font_cache_critical);
13705e2c163fSAmine Khaldi if (found_cached) return S_OK;
13715e2c163fSAmine Khaldi
13725e2c163fSAmine Khaldi GetObjectW(src_font, sizeof(font_attr), &font_attr);
13735e2c163fSAmine Khaldi font_attr.lfCharSet = (BYTE)charset_info.ciCharset;
13745e2c163fSAmine Khaldi font_attr.lfWidth = 0;
13755e2c163fSAmine Khaldi font_attr.lfFaceName[0] = 0;
13765e2c163fSAmine Khaldi new_font = CreateFontIndirectW(&font_attr);
13775e2c163fSAmine Khaldi if (new_font == NULL) continue;
13785e2c163fSAmine Khaldi
13795e2c163fSAmine Khaldi old_font = SelectObject(hdc, new_font);
13805e2c163fSAmine Khaldi charset = GetTextCharset(hdc);
13815e2c163fSAmine Khaldi SelectObject(hdc, old_font);
13825e2c163fSAmine Khaldi if (charset == charset_info.ciCharset)
13835e2c163fSAmine Khaldi {
13845e2c163fSAmine Khaldi font_list_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*font_list_entry));
13855e2c163fSAmine Khaldi if (font_list_entry == NULL) return E_OUTOFMEMORY;
13865e2c163fSAmine Khaldi
13875e2c163fSAmine Khaldi font_list_entry->base_font = src_font;
13885e2c163fSAmine Khaldi font_list_entry->font = new_font;
13895e2c163fSAmine Khaldi font_list_entry->charset = charset;
13905e2c163fSAmine Khaldi
13915e2c163fSAmine Khaldi EnterCriticalSection(&font_cache_critical);
13925e2c163fSAmine Khaldi list_add_tail(&font_cache, &font_list_entry->list_entry);
13935e2c163fSAmine Khaldi LeaveCriticalSection(&font_cache_critical);
13945e2c163fSAmine Khaldi
13955e2c163fSAmine Khaldi if (dst_font != NULL)
13965e2c163fSAmine Khaldi *dst_font = new_font;
13975e2c163fSAmine Khaldi return S_OK;
13985e2c163fSAmine Khaldi }
13995e2c163fSAmine Khaldi }
14005e2c163fSAmine Khaldi }
14015e2c163fSAmine Khaldi
14025e2c163fSAmine Khaldi return E_FAIL;
14035e2c163fSAmine Khaldi }
14045e2c163fSAmine Khaldi
release_font(HFONT font)14055e2c163fSAmine Khaldi static HRESULT release_font(HFONT font)
14065e2c163fSAmine Khaldi {
14075e2c163fSAmine Khaldi struct font_list *font_list_entry;
14085e2c163fSAmine Khaldi HRESULT hr;
14095e2c163fSAmine Khaldi
14105e2c163fSAmine Khaldi hr = E_FAIL;
14115e2c163fSAmine Khaldi EnterCriticalSection(&font_cache_critical);
14125e2c163fSAmine Khaldi LIST_FOR_EACH_ENTRY(font_list_entry, &font_cache, struct font_list, list_entry)
14135e2c163fSAmine Khaldi {
14145e2c163fSAmine Khaldi if (font_list_entry->font == font)
14155e2c163fSAmine Khaldi {
14165e2c163fSAmine Khaldi list_remove(&font_list_entry->list_entry);
14175e2c163fSAmine Khaldi DeleteObject(font);
14185e2c163fSAmine Khaldi HeapFree(GetProcessHeap(), 0, font_list_entry);
14195e2c163fSAmine Khaldi hr = S_OK;
14205e2c163fSAmine Khaldi break;
14215e2c163fSAmine Khaldi }
14225e2c163fSAmine Khaldi }
14235e2c163fSAmine Khaldi LeaveCriticalSection(&font_cache_critical);
14245e2c163fSAmine Khaldi
14255e2c163fSAmine Khaldi return hr;
14265e2c163fSAmine Khaldi }
14275e2c163fSAmine Khaldi
clear_font_cache(void)14285e2c163fSAmine Khaldi static HRESULT clear_font_cache(void)
14295e2c163fSAmine Khaldi {
14305e2c163fSAmine Khaldi struct font_list *font_list_entry;
14315e2c163fSAmine Khaldi struct font_list *font_list_entry2;
14325e2c163fSAmine Khaldi
14335e2c163fSAmine Khaldi EnterCriticalSection(&font_cache_critical);
14345e2c163fSAmine Khaldi LIST_FOR_EACH_ENTRY_SAFE(font_list_entry, font_list_entry2, &font_cache, struct font_list, list_entry)
14355e2c163fSAmine Khaldi {
14365e2c163fSAmine Khaldi list_remove(&font_list_entry->list_entry);
14375e2c163fSAmine Khaldi DeleteObject(font_list_entry->font);
14385e2c163fSAmine Khaldi HeapFree(GetProcessHeap(), 0, font_list_entry);
14395e2c163fSAmine Khaldi }
14405e2c163fSAmine Khaldi LeaveCriticalSection(&font_cache_critical);
14415e2c163fSAmine Khaldi
14425e2c163fSAmine Khaldi return S_OK;
14435e2c163fSAmine Khaldi }
14445e2c163fSAmine Khaldi
1445c2c66affSColin Finck /******************************************************************************
1446c2c66affSColin Finck * MLANG ClassFactory
1447c2c66affSColin Finck */
1448c2c66affSColin Finck typedef struct {
1449c2c66affSColin Finck IClassFactory IClassFactory_iface;
1450c2c66affSColin Finck LONG ref;
1451c2c66affSColin Finck HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
1452c2c66affSColin Finck } IClassFactoryImpl;
1453c2c66affSColin Finck
impl_from_IClassFactory(IClassFactory * iface)1454c2c66affSColin Finck static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
1455c2c66affSColin Finck {
1456c2c66affSColin Finck return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
1457c2c66affSColin Finck }
1458c2c66affSColin Finck
1459c2c66affSColin Finck struct object_creation_info
1460c2c66affSColin Finck {
1461c2c66affSColin Finck const CLSID *clsid;
1462c2c66affSColin Finck LPCSTR szClassName;
1463c2c66affSColin Finck HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
1464c2c66affSColin Finck };
1465c2c66affSColin Finck
1466c2c66affSColin Finck static const struct object_creation_info object_creation[] =
1467c2c66affSColin Finck {
1468c2c66affSColin Finck { &CLSID_CMultiLanguage, "CLSID_CMultiLanguage", MultiLanguage_create },
1469c2c66affSColin Finck { &CLSID_CMLangConvertCharset, "CLSID_CMLangConvertCharset", MLangConvertCharset_create }
1470c2c66affSColin Finck };
1471c2c66affSColin Finck
MLANGCF_QueryInterface(IClassFactory * iface,REFIID riid,void ** ppobj)1472c2c66affSColin Finck static HRESULT WINAPI MLANGCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
1473c2c66affSColin Finck {
1474c2c66affSColin Finck TRACE("%s\n", debugstr_guid(riid) );
1475c2c66affSColin Finck
1476c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown)
1477c2c66affSColin Finck || IsEqualGUID(riid, &IID_IClassFactory))
1478c2c66affSColin Finck {
1479c2c66affSColin Finck IClassFactory_AddRef(iface);
1480c2c66affSColin Finck *ppobj = iface;
1481c2c66affSColin Finck return S_OK;
1482c2c66affSColin Finck }
1483c2c66affSColin Finck
1484c2c66affSColin Finck *ppobj = NULL;
1485c2c66affSColin Finck WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj);
1486c2c66affSColin Finck return E_NOINTERFACE;
1487c2c66affSColin Finck }
1488c2c66affSColin Finck
MLANGCF_AddRef(IClassFactory * iface)1489c2c66affSColin Finck static ULONG WINAPI MLANGCF_AddRef(IClassFactory *iface)
1490c2c66affSColin Finck {
1491c2c66affSColin Finck IClassFactoryImpl *This = impl_from_IClassFactory(iface);
1492c2c66affSColin Finck return InterlockedIncrement(&This->ref);
1493c2c66affSColin Finck }
1494c2c66affSColin Finck
MLANGCF_Release(IClassFactory * iface)1495c2c66affSColin Finck static ULONG WINAPI MLANGCF_Release(IClassFactory *iface)
1496c2c66affSColin Finck {
1497c2c66affSColin Finck IClassFactoryImpl *This = impl_from_IClassFactory(iface);
1498c2c66affSColin Finck ULONG ref = InterlockedDecrement(&This->ref);
1499c2c66affSColin Finck
1500c2c66affSColin Finck if (ref == 0)
1501c2c66affSColin Finck {
1502c2c66affSColin Finck TRACE("Destroying %p\n", This);
1503c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
1504c2c66affSColin Finck }
1505c2c66affSColin Finck
1506c2c66affSColin Finck return ref;
1507c2c66affSColin Finck }
1508c2c66affSColin Finck
MLANGCF_CreateInstance(IClassFactory * iface,IUnknown * pOuter,REFIID riid,void ** ppobj)1509c2c66affSColin Finck static HRESULT WINAPI MLANGCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
1510c2c66affSColin Finck REFIID riid, void **ppobj)
1511c2c66affSColin Finck {
1512c2c66affSColin Finck IClassFactoryImpl *This = impl_from_IClassFactory(iface);
1513c2c66affSColin Finck HRESULT hres;
1514c2c66affSColin Finck LPUNKNOWN punk;
1515c2c66affSColin Finck
1516c2c66affSColin Finck TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
1517c2c66affSColin Finck
1518c2c66affSColin Finck *ppobj = NULL;
1519c2c66affSColin Finck hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
1520c2c66affSColin Finck if (SUCCEEDED(hres)) {
1521c2c66affSColin Finck hres = IUnknown_QueryInterface(punk, riid, ppobj);
1522c2c66affSColin Finck IUnknown_Release(punk);
1523c2c66affSColin Finck }
1524c2c66affSColin Finck TRACE("returning (%p) -> %x\n", *ppobj, hres);
1525c2c66affSColin Finck return hres;
1526c2c66affSColin Finck }
1527c2c66affSColin Finck
MLANGCF_LockServer(IClassFactory * iface,BOOL dolock)1528c2c66affSColin Finck static HRESULT WINAPI MLANGCF_LockServer(IClassFactory *iface, BOOL dolock)
1529c2c66affSColin Finck {
1530c2c66affSColin Finck if (dolock)
1531c2c66affSColin Finck LockModule();
1532c2c66affSColin Finck else
1533c2c66affSColin Finck UnlockModule();
1534c2c66affSColin Finck
1535c2c66affSColin Finck return S_OK;
1536c2c66affSColin Finck }
1537c2c66affSColin Finck
1538c2c66affSColin Finck static const IClassFactoryVtbl MLANGCF_Vtbl =
1539c2c66affSColin Finck {
1540c2c66affSColin Finck MLANGCF_QueryInterface,
1541c2c66affSColin Finck MLANGCF_AddRef,
1542c2c66affSColin Finck MLANGCF_Release,
1543c2c66affSColin Finck MLANGCF_CreateInstance,
1544c2c66affSColin Finck MLANGCF_LockServer
1545c2c66affSColin Finck };
1546c2c66affSColin Finck
1547c2c66affSColin Finck /******************************************************************
1548c2c66affSColin Finck * DllGetClassObject (MLANG.@)
1549c2c66affSColin Finck */
DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID * ppv)1550c2c66affSColin Finck HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
1551c2c66affSColin Finck {
1552c2c66affSColin Finck unsigned int i;
1553c2c66affSColin Finck IClassFactoryImpl *factory;
1554c2c66affSColin Finck
1555c2c66affSColin Finck TRACE("%s %s %p\n",debugstr_guid(rclsid), debugstr_guid(iid), ppv);
1556c2c66affSColin Finck
1557c2c66affSColin Finck if ( !IsEqualGUID( &IID_IClassFactory, iid )
1558c2c66affSColin Finck && ! IsEqualGUID( &IID_IUnknown, iid) )
1559c2c66affSColin Finck return E_NOINTERFACE;
1560c2c66affSColin Finck
1561ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(object_creation); i++)
1562c2c66affSColin Finck {
1563c2c66affSColin Finck if (IsEqualGUID(object_creation[i].clsid, rclsid))
1564c2c66affSColin Finck break;
1565c2c66affSColin Finck }
1566c2c66affSColin Finck
1567ccc3eeaeSAmine Khaldi if (i == ARRAY_SIZE(object_creation))
1568c2c66affSColin Finck {
1569c2c66affSColin Finck FIXME("%s: no class found.\n", debugstr_guid(rclsid));
1570c2c66affSColin Finck return CLASS_E_CLASSNOTAVAILABLE;
1571c2c66affSColin Finck }
1572c2c66affSColin Finck
1573c2c66affSColin Finck TRACE("Creating a class factory for %s\n",object_creation[i].szClassName);
1574c2c66affSColin Finck
1575c2c66affSColin Finck factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory));
1576c2c66affSColin Finck if (factory == NULL) return E_OUTOFMEMORY;
1577c2c66affSColin Finck
1578c2c66affSColin Finck factory->IClassFactory_iface.lpVtbl = &MLANGCF_Vtbl;
1579c2c66affSColin Finck factory->ref = 1;
1580c2c66affSColin Finck
1581c2c66affSColin Finck factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
1582c2c66affSColin Finck
1583c2c66affSColin Finck *ppv = &factory->IClassFactory_iface;
1584c2c66affSColin Finck
1585c2c66affSColin Finck TRACE("(%p) <- %p\n", ppv, &factory->IClassFactory_iface);
1586c2c66affSColin Finck
1587c2c66affSColin Finck return S_OK;
1588c2c66affSColin Finck }
1589c2c66affSColin Finck
1590c2c66affSColin Finck
1591c2c66affSColin Finck /******************************************************************************/
1592c2c66affSColin Finck
1593c2c66affSColin Finck typedef struct tagMLang_impl
1594c2c66affSColin Finck {
1595c2c66affSColin Finck IMLangFontLink IMLangFontLink_iface;
1596c2c66affSColin Finck IMultiLanguage IMultiLanguage_iface;
1597c2c66affSColin Finck IMultiLanguage3 IMultiLanguage3_iface;
1598c2c66affSColin Finck IMLangFontLink2 IMLangFontLink2_iface;
1599c2c66affSColin Finck IMLangLineBreakConsole IMLangLineBreakConsole_iface;
1600c2c66affSColin Finck LONG ref;
1601c2c66affSColin Finck DWORD total_cp, total_scripts;
1602c2c66affSColin Finck } MLang_impl;
1603c2c66affSColin Finck
1604c2c66affSColin Finck /******************************************************************************/
1605c2c66affSColin Finck
1606c2c66affSColin Finck typedef struct tagEnumCodePage_impl
1607c2c66affSColin Finck {
1608c2c66affSColin Finck IEnumCodePage IEnumCodePage_iface;
1609c2c66affSColin Finck LONG ref;
1610c2c66affSColin Finck MIMECPINFO *cpinfo;
1611c2c66affSColin Finck DWORD total, pos;
1612c2c66affSColin Finck } EnumCodePage_impl;
1613c2c66affSColin Finck
impl_from_IEnumCodePage(IEnumCodePage * iface)1614c2c66affSColin Finck static inline EnumCodePage_impl *impl_from_IEnumCodePage( IEnumCodePage *iface )
1615c2c66affSColin Finck {
1616c2c66affSColin Finck return CONTAINING_RECORD( iface, EnumCodePage_impl, IEnumCodePage_iface );
1617c2c66affSColin Finck }
1618c2c66affSColin Finck
fnIEnumCodePage_QueryInterface(IEnumCodePage * iface,REFIID riid,void ** ppvObject)1619c2c66affSColin Finck static HRESULT WINAPI fnIEnumCodePage_QueryInterface(
1620c2c66affSColin Finck IEnumCodePage* iface,
1621c2c66affSColin Finck REFIID riid,
1622c2c66affSColin Finck void** ppvObject)
1623c2c66affSColin Finck {
1624c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1625c2c66affSColin Finck
1626c2c66affSColin Finck TRACE("%p -> %s\n", This, debugstr_guid(riid) );
1627c2c66affSColin Finck
1628c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown)
1629c2c66affSColin Finck || IsEqualGUID(riid, &IID_IEnumCodePage))
1630c2c66affSColin Finck {
1631c2c66affSColin Finck IEnumCodePage_AddRef(iface);
1632c2c66affSColin Finck TRACE("Returning IID_IEnumCodePage %p ref = %d\n", This, This->ref);
1633c2c66affSColin Finck *ppvObject = &This->IEnumCodePage_iface;
1634c2c66affSColin Finck return S_OK;
1635c2c66affSColin Finck }
1636c2c66affSColin Finck
1637c2c66affSColin Finck WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1638c2c66affSColin Finck return E_NOINTERFACE;
1639c2c66affSColin Finck }
1640c2c66affSColin Finck
fnIEnumCodePage_AddRef(IEnumCodePage * iface)1641c2c66affSColin Finck static ULONG WINAPI fnIEnumCodePage_AddRef(
1642c2c66affSColin Finck IEnumCodePage* iface)
1643c2c66affSColin Finck {
1644c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1645c2c66affSColin Finck return InterlockedIncrement(&This->ref);
1646c2c66affSColin Finck }
1647c2c66affSColin Finck
fnIEnumCodePage_Release(IEnumCodePage * iface)1648c2c66affSColin Finck static ULONG WINAPI fnIEnumCodePage_Release(
1649c2c66affSColin Finck IEnumCodePage* iface)
1650c2c66affSColin Finck {
1651c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1652c2c66affSColin Finck ULONG ref = InterlockedDecrement(&This->ref);
1653c2c66affSColin Finck
1654c2c66affSColin Finck TRACE("%p ref = %d\n", This, ref);
1655c2c66affSColin Finck if (ref == 0)
1656c2c66affSColin Finck {
1657c2c66affSColin Finck TRACE("Destroying %p\n", This);
1658c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This->cpinfo);
1659c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
1660c2c66affSColin Finck }
1661c2c66affSColin Finck
1662c2c66affSColin Finck return ref;
1663c2c66affSColin Finck }
1664c2c66affSColin Finck
fnIEnumCodePage_Clone(IEnumCodePage * iface,IEnumCodePage ** ppEnum)1665c2c66affSColin Finck static HRESULT WINAPI fnIEnumCodePage_Clone(
1666c2c66affSColin Finck IEnumCodePage* iface,
1667c2c66affSColin Finck IEnumCodePage** ppEnum)
1668c2c66affSColin Finck {
1669c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1670c2c66affSColin Finck FIXME("%p %p\n", This, ppEnum);
1671c2c66affSColin Finck return E_NOTIMPL;
1672c2c66affSColin Finck }
1673c2c66affSColin Finck
fnIEnumCodePage_Next(IEnumCodePage * iface,ULONG celt,PMIMECPINFO rgelt,ULONG * pceltFetched)1674c2c66affSColin Finck static HRESULT WINAPI fnIEnumCodePage_Next(
1675c2c66affSColin Finck IEnumCodePage* iface,
1676c2c66affSColin Finck ULONG celt,
1677c2c66affSColin Finck PMIMECPINFO rgelt,
1678c2c66affSColin Finck ULONG* pceltFetched)
1679c2c66affSColin Finck {
1680c2c66affSColin Finck ULONG i;
1681c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1682c2c66affSColin Finck
1683c2c66affSColin Finck TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched);
1684c2c66affSColin Finck
1685c2c66affSColin Finck if (!pceltFetched) return S_FALSE;
1686c2c66affSColin Finck *pceltFetched = 0;
1687c2c66affSColin Finck
1688c2c66affSColin Finck if (!rgelt) return S_FALSE;
1689c2c66affSColin Finck
1690c2c66affSColin Finck if (This->pos + celt > This->total)
1691c2c66affSColin Finck celt = This->total - This->pos;
1692c2c66affSColin Finck
1693c2c66affSColin Finck if (!celt) return S_FALSE;
1694c2c66affSColin Finck
1695c2c66affSColin Finck memcpy(rgelt, This->cpinfo + This->pos, celt * sizeof(MIMECPINFO));
1696c2c66affSColin Finck *pceltFetched = celt;
1697c2c66affSColin Finck This->pos += celt;
1698c2c66affSColin Finck
1699c2c66affSColin Finck for (i = 0; i < celt; i++)
1700c2c66affSColin Finck {
1701c2c66affSColin Finck TRACE("#%u: %08x %u %u %s %s %s %s %s %s %d\n",
1702c2c66affSColin Finck i, rgelt[i].dwFlags, rgelt[i].uiCodePage,
1703c2c66affSColin Finck rgelt[i].uiFamilyCodePage,
1704c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszDescription),
1705c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszWebCharset),
1706c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszHeaderCharset),
1707c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszBodyCharset),
1708c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszFixedWidthFont),
1709c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszProportionalFont),
1710c2c66affSColin Finck rgelt[i].bGDICharset);
1711c2c66affSColin Finck }
1712c2c66affSColin Finck return S_OK;
1713c2c66affSColin Finck }
1714c2c66affSColin Finck
fnIEnumCodePage_Reset(IEnumCodePage * iface)1715c2c66affSColin Finck static HRESULT WINAPI fnIEnumCodePage_Reset(
1716c2c66affSColin Finck IEnumCodePage* iface)
1717c2c66affSColin Finck {
1718c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1719c2c66affSColin Finck
1720c2c66affSColin Finck TRACE("%p\n", This);
1721c2c66affSColin Finck
1722c2c66affSColin Finck This->pos = 0;
1723c2c66affSColin Finck return S_OK;
1724c2c66affSColin Finck }
1725c2c66affSColin Finck
fnIEnumCodePage_Skip(IEnumCodePage * iface,ULONG celt)1726c2c66affSColin Finck static HRESULT WINAPI fnIEnumCodePage_Skip(
1727c2c66affSColin Finck IEnumCodePage* iface,
1728c2c66affSColin Finck ULONG celt)
1729c2c66affSColin Finck {
1730c2c66affSColin Finck EnumCodePage_impl *This = impl_from_IEnumCodePage( iface );
1731c2c66affSColin Finck
1732c2c66affSColin Finck TRACE("%p %u\n", This, celt);
1733c2c66affSColin Finck
1734c2c66affSColin Finck if (celt >= This->total) return S_FALSE;
1735c2c66affSColin Finck
1736c2c66affSColin Finck This->pos += celt;
1737c2c66affSColin Finck return S_OK;
1738c2c66affSColin Finck }
1739c2c66affSColin Finck
1740c2c66affSColin Finck static const IEnumCodePageVtbl IEnumCodePage_vtbl =
1741c2c66affSColin Finck {
1742c2c66affSColin Finck fnIEnumCodePage_QueryInterface,
1743c2c66affSColin Finck fnIEnumCodePage_AddRef,
1744c2c66affSColin Finck fnIEnumCodePage_Release,
1745c2c66affSColin Finck fnIEnumCodePage_Clone,
1746c2c66affSColin Finck fnIEnumCodePage_Next,
1747c2c66affSColin Finck fnIEnumCodePage_Reset,
1748c2c66affSColin Finck fnIEnumCodePage_Skip
1749c2c66affSColin Finck };
1750c2c66affSColin Finck
EnumCodePage_create(MLang_impl * mlang,DWORD grfFlags,LANGID LangId,IEnumCodePage ** ppEnumCodePage)1751c2c66affSColin Finck static HRESULT EnumCodePage_create( MLang_impl* mlang, DWORD grfFlags,
1752c2c66affSColin Finck LANGID LangId, IEnumCodePage** ppEnumCodePage )
1753c2c66affSColin Finck {
1754c2c66affSColin Finck EnumCodePage_impl *ecp;
1755c2c66affSColin Finck MIMECPINFO *cpinfo;
1756c2c66affSColin Finck UINT i, n;
1757c2c66affSColin Finck
1758c2c66affSColin Finck TRACE("%p, %08x, %04x, %p\n", mlang, grfFlags, LangId, ppEnumCodePage);
1759c2c66affSColin Finck
1760c2c66affSColin Finck if (!grfFlags) /* enumerate internal data base of encodings */
1761c2c66affSColin Finck grfFlags = MIMECONTF_MIME_LATEST;
1762c2c66affSColin Finck
1763c2c66affSColin Finck ecp = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumCodePage_impl) );
1764c2c66affSColin Finck ecp->IEnumCodePage_iface.lpVtbl = &IEnumCodePage_vtbl;
1765c2c66affSColin Finck ecp->ref = 1;
1766c2c66affSColin Finck ecp->pos = 0;
1767c2c66affSColin Finck ecp->total = 0;
1768ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
1769c2c66affSColin Finck {
1770c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
1771c2c66affSColin Finck {
1772c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].flags & grfFlags)
1773c2c66affSColin Finck ecp->total++;
1774c2c66affSColin Finck }
1775c2c66affSColin Finck }
1776c2c66affSColin Finck
1777c2c66affSColin Finck ecp->cpinfo = HeapAlloc(GetProcessHeap(), 0,
1778c2c66affSColin Finck sizeof(MIMECPINFO) * ecp->total);
1779c2c66affSColin Finck cpinfo = ecp->cpinfo;
1780c2c66affSColin Finck
1781ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
1782c2c66affSColin Finck {
1783c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
1784c2c66affSColin Finck {
1785c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].flags & grfFlags)
1786c2c66affSColin Finck fill_cp_info(&mlang_data[i], n, cpinfo++);
1787c2c66affSColin Finck }
1788c2c66affSColin Finck }
1789c2c66affSColin Finck
1790c2c66affSColin Finck TRACE("enumerated %d codepages with flags %08x\n", ecp->total, grfFlags);
1791c2c66affSColin Finck
1792c2c66affSColin Finck *ppEnumCodePage = &ecp->IEnumCodePage_iface;
1793c2c66affSColin Finck
1794c2c66affSColin Finck return S_OK;
1795c2c66affSColin Finck }
1796c2c66affSColin Finck
1797c2c66affSColin Finck /******************************************************************************/
1798c2c66affSColin Finck
1799c2c66affSColin Finck typedef struct tagEnumScript_impl
1800c2c66affSColin Finck {
1801c2c66affSColin Finck IEnumScript IEnumScript_iface;
1802c2c66affSColin Finck LONG ref;
1803c2c66affSColin Finck SCRIPTINFO *script_info;
1804c2c66affSColin Finck DWORD total, pos;
1805c2c66affSColin Finck } EnumScript_impl;
1806c2c66affSColin Finck
impl_from_IEnumScript(IEnumScript * iface)1807c2c66affSColin Finck static inline EnumScript_impl *impl_from_IEnumScript( IEnumScript *iface )
1808c2c66affSColin Finck {
1809c2c66affSColin Finck return CONTAINING_RECORD( iface, EnumScript_impl, IEnumScript_iface );
1810c2c66affSColin Finck }
1811c2c66affSColin Finck
fnIEnumScript_QueryInterface(IEnumScript * iface,REFIID riid,void ** ppvObject)1812c2c66affSColin Finck static HRESULT WINAPI fnIEnumScript_QueryInterface(
1813c2c66affSColin Finck IEnumScript* iface,
1814c2c66affSColin Finck REFIID riid,
1815c2c66affSColin Finck void** ppvObject)
1816c2c66affSColin Finck {
1817c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1818c2c66affSColin Finck
1819c2c66affSColin Finck TRACE("%p -> %s\n", This, debugstr_guid(riid) );
1820c2c66affSColin Finck
1821c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown)
1822c2c66affSColin Finck || IsEqualGUID(riid, &IID_IEnumScript))
1823c2c66affSColin Finck {
1824c2c66affSColin Finck IEnumScript_AddRef(iface);
1825c2c66affSColin Finck TRACE("Returning IID_IEnumScript %p ref = %d\n", This, This->ref);
1826c2c66affSColin Finck *ppvObject = &This->IEnumScript_iface;
1827c2c66affSColin Finck return S_OK;
1828c2c66affSColin Finck }
1829c2c66affSColin Finck
1830c2c66affSColin Finck WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1831c2c66affSColin Finck return E_NOINTERFACE;
1832c2c66affSColin Finck }
1833c2c66affSColin Finck
fnIEnumScript_AddRef(IEnumScript * iface)1834c2c66affSColin Finck static ULONG WINAPI fnIEnumScript_AddRef(
1835c2c66affSColin Finck IEnumScript* iface)
1836c2c66affSColin Finck {
1837c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1838c2c66affSColin Finck return InterlockedIncrement(&This->ref);
1839c2c66affSColin Finck }
1840c2c66affSColin Finck
fnIEnumScript_Release(IEnumScript * iface)1841c2c66affSColin Finck static ULONG WINAPI fnIEnumScript_Release(
1842c2c66affSColin Finck IEnumScript* iface)
1843c2c66affSColin Finck {
1844c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1845c2c66affSColin Finck ULONG ref = InterlockedDecrement(&This->ref);
1846c2c66affSColin Finck
1847c2c66affSColin Finck TRACE("%p ref = %d\n", This, ref);
1848c2c66affSColin Finck if (ref == 0)
1849c2c66affSColin Finck {
1850c2c66affSColin Finck TRACE("Destroying %p\n", This);
1851c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This->script_info);
1852c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
1853c2c66affSColin Finck }
1854c2c66affSColin Finck
1855c2c66affSColin Finck return ref;
1856c2c66affSColin Finck }
1857c2c66affSColin Finck
fnIEnumScript_Clone(IEnumScript * iface,IEnumScript ** ppEnum)1858c2c66affSColin Finck static HRESULT WINAPI fnIEnumScript_Clone(
1859c2c66affSColin Finck IEnumScript* iface,
1860c2c66affSColin Finck IEnumScript** ppEnum)
1861c2c66affSColin Finck {
1862c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1863c2c66affSColin Finck FIXME("%p %p: stub!\n", This, ppEnum);
1864c2c66affSColin Finck return E_NOTIMPL;
1865c2c66affSColin Finck }
1866c2c66affSColin Finck
fnIEnumScript_Next(IEnumScript * iface,ULONG celt,PSCRIPTINFO rgelt,ULONG * pceltFetched)1867c2c66affSColin Finck static HRESULT WINAPI fnIEnumScript_Next(
1868c2c66affSColin Finck IEnumScript* iface,
1869c2c66affSColin Finck ULONG celt,
1870c2c66affSColin Finck PSCRIPTINFO rgelt,
1871c2c66affSColin Finck ULONG* pceltFetched)
1872c2c66affSColin Finck {
1873c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1874c2c66affSColin Finck
1875c2c66affSColin Finck TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched);
1876c2c66affSColin Finck
1877c2c66affSColin Finck if (!pceltFetched || !rgelt) return E_FAIL;
1878c2c66affSColin Finck
1879c2c66affSColin Finck *pceltFetched = 0;
1880c2c66affSColin Finck
1881c2c66affSColin Finck if (This->pos + celt > This->total)
1882c2c66affSColin Finck celt = This->total - This->pos;
1883c2c66affSColin Finck
1884c2c66affSColin Finck if (!celt) return S_FALSE;
1885c2c66affSColin Finck
1886c2c66affSColin Finck memcpy(rgelt, This->script_info + This->pos, celt * sizeof(SCRIPTINFO));
1887c2c66affSColin Finck *pceltFetched = celt;
1888c2c66affSColin Finck This->pos += celt;
1889c2c66affSColin Finck
1890c2c66affSColin Finck return S_OK;
1891c2c66affSColin Finck }
1892c2c66affSColin Finck
fnIEnumScript_Reset(IEnumScript * iface)1893c2c66affSColin Finck static HRESULT WINAPI fnIEnumScript_Reset(
1894c2c66affSColin Finck IEnumScript* iface)
1895c2c66affSColin Finck {
1896c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1897c2c66affSColin Finck
1898c2c66affSColin Finck TRACE("%p\n", This);
1899c2c66affSColin Finck
1900c2c66affSColin Finck This->pos = 0;
1901c2c66affSColin Finck return S_OK;
1902c2c66affSColin Finck }
1903c2c66affSColin Finck
fnIEnumScript_Skip(IEnumScript * iface,ULONG celt)1904c2c66affSColin Finck static HRESULT WINAPI fnIEnumScript_Skip(
1905c2c66affSColin Finck IEnumScript* iface,
1906c2c66affSColin Finck ULONG celt)
1907c2c66affSColin Finck {
1908c2c66affSColin Finck EnumScript_impl *This = impl_from_IEnumScript( iface );
1909c2c66affSColin Finck
1910c2c66affSColin Finck TRACE("%p %u\n", This, celt);
1911c2c66affSColin Finck
1912c2c66affSColin Finck if (celt >= This->total) return S_FALSE;
1913c2c66affSColin Finck
1914c2c66affSColin Finck This->pos += celt;
1915c2c66affSColin Finck return S_OK;
1916c2c66affSColin Finck }
1917c2c66affSColin Finck
1918c2c66affSColin Finck static const IEnumScriptVtbl IEnumScript_vtbl =
1919c2c66affSColin Finck {
1920c2c66affSColin Finck fnIEnumScript_QueryInterface,
1921c2c66affSColin Finck fnIEnumScript_AddRef,
1922c2c66affSColin Finck fnIEnumScript_Release,
1923c2c66affSColin Finck fnIEnumScript_Clone,
1924c2c66affSColin Finck fnIEnumScript_Next,
1925c2c66affSColin Finck fnIEnumScript_Reset,
1926c2c66affSColin Finck fnIEnumScript_Skip
1927c2c66affSColin Finck };
1928c2c66affSColin Finck
EnumScript_create(MLang_impl * mlang,DWORD dwFlags,LANGID LangId,IEnumScript ** ppEnumScript)1929c2c66affSColin Finck static HRESULT EnumScript_create( MLang_impl* mlang, DWORD dwFlags,
1930c2c66affSColin Finck LANGID LangId, IEnumScript** ppEnumScript )
1931c2c66affSColin Finck {
1932c2c66affSColin Finck EnumScript_impl *es;
1933c2c66affSColin Finck UINT i;
1934c2c66affSColin Finck
1935c2c66affSColin Finck TRACE("%p, %08x, %04x, %p\n", mlang, dwFlags, LangId, ppEnumScript);
1936c2c66affSColin Finck
1937c2c66affSColin Finck if (!dwFlags) /* enumerate all available scripts */
1938c2c66affSColin Finck dwFlags = SCRIPTCONTF_SCRIPT_USER | SCRIPTCONTF_SCRIPT_HIDE | SCRIPTCONTF_SCRIPT_SYSTEM;
1939c2c66affSColin Finck
1940c2c66affSColin Finck es = HeapAlloc( GetProcessHeap(), 0, sizeof (EnumScript_impl) );
1941c2c66affSColin Finck es->IEnumScript_iface.lpVtbl = &IEnumScript_vtbl;
1942c2c66affSColin Finck es->ref = 1;
1943c2c66affSColin Finck es->pos = 0;
1944c2c66affSColin Finck /* do not enumerate unicode flavours */
1945ccc3eeaeSAmine Khaldi es->total = ARRAY_SIZE(mlang_data) - 1;
1946c2c66affSColin Finck es->script_info = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPTINFO) * es->total);
1947c2c66affSColin Finck
1948c2c66affSColin Finck for (i = 0; i < es->total; i++)
1949c2c66affSColin Finck {
1950c2c66affSColin Finck es->script_info[i].ScriptId = i;
1951c2c66affSColin Finck es->script_info[i].uiCodePage = mlang_data[i].family_codepage;
1952c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].description, -1,
1953c2c66affSColin Finck es->script_info[i].wszDescription, MAX_SCRIPT_NAME);
1954c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].fixed_font, -1,
1955c2c66affSColin Finck es->script_info[i].wszFixedWidthFont, MAX_MIMEFACE_NAME);
1956c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].proportional_font, -1,
1957c2c66affSColin Finck es->script_info[i].wszProportionalFont, MAX_MIMEFACE_NAME);
1958c2c66affSColin Finck }
1959c2c66affSColin Finck
1960c2c66affSColin Finck TRACE("enumerated %d scripts with flags %08x\n", es->total, dwFlags);
1961c2c66affSColin Finck
1962c2c66affSColin Finck *ppEnumScript = &es->IEnumScript_iface;
1963c2c66affSColin Finck
1964c2c66affSColin Finck return S_OK;
1965c2c66affSColin Finck }
1966c2c66affSColin Finck
1967c2c66affSColin Finck /******************************************************************************/
1968c2c66affSColin Finck
impl_from_IMLangFontLink(IMLangFontLink * iface)1969c2c66affSColin Finck static inline MLang_impl *impl_from_IMLangFontLink( IMLangFontLink *iface )
1970c2c66affSColin Finck {
1971c2c66affSColin Finck return CONTAINING_RECORD( iface, MLang_impl, IMLangFontLink_iface );
1972c2c66affSColin Finck }
1973c2c66affSColin Finck
fnIMLangFontLink_QueryInterface(IMLangFontLink * iface,REFIID riid,void ** ppvObject)1974c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_QueryInterface(
1975c2c66affSColin Finck IMLangFontLink* iface,
1976c2c66affSColin Finck REFIID riid,
1977c2c66affSColin Finck void** ppvObject)
1978c2c66affSColin Finck {
1979c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink( iface );
1980c2c66affSColin Finck return IMultiLanguage3_QueryInterface( &This->IMultiLanguage3_iface, riid, ppvObject );
1981c2c66affSColin Finck }
1982c2c66affSColin Finck
fnIMLangFontLink_AddRef(IMLangFontLink * iface)1983c2c66affSColin Finck static ULONG WINAPI fnIMLangFontLink_AddRef(
1984c2c66affSColin Finck IMLangFontLink* iface)
1985c2c66affSColin Finck {
1986c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink( iface );
1987c2c66affSColin Finck return IMultiLanguage3_AddRef( &This->IMultiLanguage3_iface );
1988c2c66affSColin Finck }
1989c2c66affSColin Finck
fnIMLangFontLink_Release(IMLangFontLink * iface)1990c2c66affSColin Finck static ULONG WINAPI fnIMLangFontLink_Release(
1991c2c66affSColin Finck IMLangFontLink* iface)
1992c2c66affSColin Finck {
1993c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink( iface );
1994c2c66affSColin Finck return IMultiLanguage3_Release( &This->IMultiLanguage3_iface );
1995c2c66affSColin Finck }
1996c2c66affSColin Finck
fnIMLangFontLink_GetCharCodePages(IMLangFontLink * iface,WCHAR ch_src,DWORD * codepages)1997c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_GetCharCodePages(
1998c2c66affSColin Finck IMLangFontLink* iface,
1999c2c66affSColin Finck WCHAR ch_src,
2000c2c66affSColin Finck DWORD* codepages)
2001c2c66affSColin Finck {
2002c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink( iface );
2003c2c66affSColin Finck return IMLangFontLink2_GetCharCodePages(&This->IMLangFontLink2_iface, ch_src, codepages);
2004c2c66affSColin Finck }
2005c2c66affSColin Finck
fnIMLangFontLink_GetStrCodePages(IMLangFontLink * iface,const WCHAR * src,LONG src_len,DWORD priority_cp,DWORD * codepages,LONG * ret_len)2006c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_GetStrCodePages(
2007c2c66affSColin Finck IMLangFontLink* iface,
2008c2c66affSColin Finck const WCHAR* src,
2009c2c66affSColin Finck LONG src_len,
2010c2c66affSColin Finck DWORD priority_cp,
2011c2c66affSColin Finck DWORD* codepages,
2012c2c66affSColin Finck LONG* ret_len)
2013c2c66affSColin Finck {
2014c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink( iface );
2015c2c66affSColin Finck return IMLangFontLink2_GetStrCodePages(&This->IMLangFontLink2_iface, src, src_len, priority_cp,
2016c2c66affSColin Finck codepages, ret_len);
2017c2c66affSColin Finck }
2018c2c66affSColin Finck
fnIMLangFontLink_CodePageToCodePages(IMLangFontLink * iface,UINT codepage,DWORD * codepages)2019c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_CodePageToCodePages(
2020c2c66affSColin Finck IMLangFontLink* iface,
2021c2c66affSColin Finck UINT codepage,
2022c2c66affSColin Finck DWORD* codepages)
2023c2c66affSColin Finck {
2024c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink( iface );
2025c2c66affSColin Finck return IMLangFontLink2_CodePageToCodePages(&This->IMLangFontLink2_iface, codepage, codepages);
2026c2c66affSColin Finck }
2027c2c66affSColin Finck
fnIMLangFontLink_CodePagesToCodePage(IMLangFontLink * iface,DWORD codepages,UINT def_codepage,UINT * codepage)2028c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_CodePagesToCodePage(
2029c2c66affSColin Finck IMLangFontLink* iface,
2030c2c66affSColin Finck DWORD codepages,
2031c2c66affSColin Finck UINT def_codepage,
2032c2c66affSColin Finck UINT* codepage)
2033c2c66affSColin Finck {
2034c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink(iface);
2035c2c66affSColin Finck return IMLangFontLink2_CodePagesToCodePage(&This->IMLangFontLink2_iface, codepages,
2036c2c66affSColin Finck def_codepage, codepage);
2037c2c66affSColin Finck }
2038c2c66affSColin Finck
fnIMLangFontLink_GetFontCodePages(IMLangFontLink * iface,HDC hdc,HFONT hfont,DWORD * codepages)2039c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_GetFontCodePages(
2040c2c66affSColin Finck IMLangFontLink* iface,
2041c2c66affSColin Finck HDC hdc,
2042c2c66affSColin Finck HFONT hfont,
2043c2c66affSColin Finck DWORD* codepages)
2044c2c66affSColin Finck {
2045c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink(iface);
2046c2c66affSColin Finck return IMLangFontLink2_GetFontCodePages(&This->IMLangFontLink2_iface, hdc, hfont, codepages);
2047c2c66affSColin Finck }
2048c2c66affSColin Finck
fnIMLangFontLink_MapFont(IMLangFontLink * iface,HDC hDC,DWORD dwCodePages,HFONT hSrcFont,HFONT * phDestFont)2049c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_MapFont(
2050c2c66affSColin Finck IMLangFontLink* iface,
2051c2c66affSColin Finck HDC hDC,
2052c2c66affSColin Finck DWORD dwCodePages,
2053c2c66affSColin Finck HFONT hSrcFont,
2054c2c66affSColin Finck HFONT* phDestFont)
2055c2c66affSColin Finck {
20565e2c163fSAmine Khaldi TRACE("(%p)->%p %08x %p %p\n",iface, hDC, dwCodePages, hSrcFont, phDestFont);
20575e2c163fSAmine Khaldi
20585e2c163fSAmine Khaldi return map_font(hDC, dwCodePages, hSrcFont, phDestFont);
2059c2c66affSColin Finck }
2060c2c66affSColin Finck
fnIMLangFontLink_ReleaseFont(IMLangFontLink * iface,HFONT hFont)2061c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_ReleaseFont(
2062c2c66affSColin Finck IMLangFontLink* iface,
2063c2c66affSColin Finck HFONT hFont)
2064c2c66affSColin Finck {
20655e2c163fSAmine Khaldi TRACE("(%p)->%p\n",iface, hFont);
20665e2c163fSAmine Khaldi
20675e2c163fSAmine Khaldi return release_font(hFont);
2068c2c66affSColin Finck }
2069c2c66affSColin Finck
fnIMLangFontLink_ResetFontMapping(IMLangFontLink * iface)2070c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink_ResetFontMapping(
2071c2c66affSColin Finck IMLangFontLink* iface)
2072c2c66affSColin Finck {
20735e2c163fSAmine Khaldi TRACE("(%p)\n",iface);
20745e2c163fSAmine Khaldi
20755e2c163fSAmine Khaldi return clear_font_cache();
2076c2c66affSColin Finck }
2077c2c66affSColin Finck
2078c2c66affSColin Finck
2079c2c66affSColin Finck static const IMLangFontLinkVtbl IMLangFontLink_vtbl =
2080c2c66affSColin Finck {
2081c2c66affSColin Finck fnIMLangFontLink_QueryInterface,
2082c2c66affSColin Finck fnIMLangFontLink_AddRef,
2083c2c66affSColin Finck fnIMLangFontLink_Release,
2084c2c66affSColin Finck fnIMLangFontLink_GetCharCodePages,
2085c2c66affSColin Finck fnIMLangFontLink_GetStrCodePages,
2086c2c66affSColin Finck fnIMLangFontLink_CodePageToCodePages,
2087c2c66affSColin Finck fnIMLangFontLink_CodePagesToCodePage,
2088c2c66affSColin Finck fnIMLangFontLink_GetFontCodePages,
2089c2c66affSColin Finck fnIMLangFontLink_MapFont,
2090c2c66affSColin Finck fnIMLangFontLink_ReleaseFont,
2091c2c66affSColin Finck fnIMLangFontLink_ResetFontMapping,
2092c2c66affSColin Finck };
2093c2c66affSColin Finck
2094c2c66affSColin Finck /******************************************************************************/
2095c2c66affSColin Finck
impl_from_IMultiLanguage(IMultiLanguage * iface)2096c2c66affSColin Finck static inline MLang_impl *impl_from_IMultiLanguage( IMultiLanguage *iface )
2097c2c66affSColin Finck {
2098c2c66affSColin Finck return CONTAINING_RECORD( iface, MLang_impl, IMultiLanguage_iface );
2099c2c66affSColin Finck }
2100c2c66affSColin Finck
fnIMultiLanguage_QueryInterface(IMultiLanguage * iface,REFIID riid,void ** obj)2101c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_QueryInterface(
2102c2c66affSColin Finck IMultiLanguage* iface,
2103c2c66affSColin Finck REFIID riid,
2104c2c66affSColin Finck void** obj)
2105c2c66affSColin Finck {
2106c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2107c2c66affSColin Finck return IMultiLanguage3_QueryInterface(&This->IMultiLanguage3_iface, riid, obj);
2108c2c66affSColin Finck }
2109c2c66affSColin Finck
fnIMultiLanguage_AddRef(IMultiLanguage * iface)2110c2c66affSColin Finck static ULONG WINAPI fnIMultiLanguage_AddRef( IMultiLanguage* iface )
2111c2c66affSColin Finck {
2112c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2113c2c66affSColin Finck return IMultiLanguage3_AddRef(&This->IMultiLanguage3_iface);
2114c2c66affSColin Finck }
2115c2c66affSColin Finck
fnIMultiLanguage_Release(IMultiLanguage * iface)2116c2c66affSColin Finck static ULONG WINAPI fnIMultiLanguage_Release( IMultiLanguage* iface )
2117c2c66affSColin Finck {
2118c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2119c2c66affSColin Finck return IMultiLanguage3_Release(&This->IMultiLanguage3_iface);
2120c2c66affSColin Finck }
2121c2c66affSColin Finck
fnIMultiLanguage_GetNumberOfCodePageInfo(IMultiLanguage * iface,UINT * cp)2122c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetNumberOfCodePageInfo(
2123c2c66affSColin Finck IMultiLanguage* iface,
2124c2c66affSColin Finck UINT* cp)
2125c2c66affSColin Finck {
2126c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2127c2c66affSColin Finck TRACE("(%p, %p)\n", This, cp);
2128c2c66affSColin Finck return IMultiLanguage3_GetNumberOfCodePageInfo(&This->IMultiLanguage3_iface, cp);
2129c2c66affSColin Finck }
2130c2c66affSColin Finck
fnIMultiLanguage_GetCodePageInfo(IMultiLanguage * iface,UINT uiCodePage,PMIMECPINFO pCodePageInfo)2131c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetCodePageInfo(
2132c2c66affSColin Finck IMultiLanguage* iface,
2133c2c66affSColin Finck UINT uiCodePage,
2134c2c66affSColin Finck PMIMECPINFO pCodePageInfo)
2135c2c66affSColin Finck {
2136c2c66affSColin Finck UINT i, n;
2137c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2138c2c66affSColin Finck
2139c2c66affSColin Finck TRACE("%p, %u, %p\n", This, uiCodePage, pCodePageInfo);
2140c2c66affSColin Finck
2141ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
2142c2c66affSColin Finck {
2143c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
2144c2c66affSColin Finck {
2145c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
2146c2c66affSColin Finck {
2147c2c66affSColin Finck fill_cp_info(&mlang_data[i], n, pCodePageInfo);
2148c2c66affSColin Finck return S_OK;
2149c2c66affSColin Finck }
2150c2c66affSColin Finck }
2151c2c66affSColin Finck }
2152c2c66affSColin Finck
2153c2c66affSColin Finck return S_FALSE;
2154c2c66affSColin Finck }
2155c2c66affSColin Finck
fnIMultiLanguage_GetFamilyCodePage(IMultiLanguage * iface,UINT cp,UINT * family_cp)2156c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetFamilyCodePage(
2157c2c66affSColin Finck IMultiLanguage* iface,
2158c2c66affSColin Finck UINT cp,
2159c2c66affSColin Finck UINT* family_cp)
2160c2c66affSColin Finck {
2161c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2162c2c66affSColin Finck return IMultiLanguage3_GetFamilyCodePage(&This->IMultiLanguage3_iface, cp, family_cp);
2163c2c66affSColin Finck }
2164c2c66affSColin Finck
fnIMultiLanguage_EnumCodePages(IMultiLanguage * iface,DWORD grfFlags,IEnumCodePage ** ppEnumCodePage)2165c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_EnumCodePages(
2166c2c66affSColin Finck IMultiLanguage* iface,
2167c2c66affSColin Finck DWORD grfFlags,
2168c2c66affSColin Finck IEnumCodePage** ppEnumCodePage)
2169c2c66affSColin Finck {
2170c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2171c2c66affSColin Finck
2172c2c66affSColin Finck TRACE("%p %08x %p\n", This, grfFlags, ppEnumCodePage);
2173c2c66affSColin Finck
2174c2c66affSColin Finck return EnumCodePage_create( This, grfFlags, 0, ppEnumCodePage );
2175c2c66affSColin Finck }
2176c2c66affSColin Finck
fnIMultiLanguage_GetCharsetInfo(IMultiLanguage * iface,BSTR Charset,PMIMECSETINFO pCharsetInfo)2177c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetCharsetInfo(
2178c2c66affSColin Finck IMultiLanguage* iface,
2179c2c66affSColin Finck BSTR Charset,
2180c2c66affSColin Finck PMIMECSETINFO pCharsetInfo)
2181c2c66affSColin Finck {
2182c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2183c2c66affSColin Finck return IMultiLanguage3_GetCharsetInfo( &This->IMultiLanguage3_iface, Charset, pCharsetInfo );
2184c2c66affSColin Finck }
2185c2c66affSColin Finck
fnIMultiLanguage_IsConvertible(IMultiLanguage * iface,DWORD src_enc,DWORD dst_enc)2186c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_IsConvertible(
2187c2c66affSColin Finck IMultiLanguage* iface,
2188c2c66affSColin Finck DWORD src_enc,
2189c2c66affSColin Finck DWORD dst_enc)
2190c2c66affSColin Finck {
2191c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2192c2c66affSColin Finck return IMultiLanguage3_IsConvertible(&This->IMultiLanguage3_iface, src_enc, dst_enc);
2193c2c66affSColin Finck }
2194c2c66affSColin Finck
fnIMultiLanguage_ConvertString(IMultiLanguage * iface,DWORD * mode,DWORD src_enc,DWORD dst_enc,BYTE * src,UINT * src_size,BYTE * dest,UINT * dest_size)2195c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_ConvertString(
2196c2c66affSColin Finck IMultiLanguage* iface,
2197c2c66affSColin Finck DWORD* mode,
2198c2c66affSColin Finck DWORD src_enc,
2199c2c66affSColin Finck DWORD dst_enc,
2200c2c66affSColin Finck BYTE* src,
2201c2c66affSColin Finck UINT* src_size,
2202c2c66affSColin Finck BYTE* dest,
2203c2c66affSColin Finck UINT* dest_size)
2204c2c66affSColin Finck {
2205c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2206c2c66affSColin Finck return IMultiLanguage3_ConvertString(&This->IMultiLanguage3_iface, mode, src_enc,
2207c2c66affSColin Finck dst_enc, src, src_size, dest, dest_size);
2208c2c66affSColin Finck }
2209c2c66affSColin Finck
fnIMultiLanguage_ConvertStringToUnicode(IMultiLanguage * iface,DWORD * mode,DWORD src_enc,CHAR * src,UINT * src_size,WCHAR * dest,UINT * dest_size)2210c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_ConvertStringToUnicode(
2211c2c66affSColin Finck IMultiLanguage* iface,
2212c2c66affSColin Finck DWORD* mode,
2213c2c66affSColin Finck DWORD src_enc,
2214c2c66affSColin Finck CHAR* src,
2215c2c66affSColin Finck UINT* src_size,
2216c2c66affSColin Finck WCHAR* dest,
2217c2c66affSColin Finck UINT* dest_size)
2218c2c66affSColin Finck {
2219c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2220c2c66affSColin Finck return IMultiLanguage3_ConvertStringToUnicode(&This->IMultiLanguage3_iface,
2221c2c66affSColin Finck mode, src_enc, src, src_size, dest, dest_size);
2222c2c66affSColin Finck }
2223c2c66affSColin Finck
fnIMultiLanguage_ConvertStringFromUnicode(IMultiLanguage * iface,DWORD * mode,DWORD encoding,WCHAR * src,UINT * src_size,CHAR * dest,UINT * dest_size)2224c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_ConvertStringFromUnicode(
2225c2c66affSColin Finck IMultiLanguage* iface,
2226c2c66affSColin Finck DWORD* mode,
2227c2c66affSColin Finck DWORD encoding,
2228c2c66affSColin Finck WCHAR* src,
2229c2c66affSColin Finck UINT* src_size,
2230c2c66affSColin Finck CHAR* dest,
2231c2c66affSColin Finck UINT* dest_size)
2232c2c66affSColin Finck {
2233c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage(iface);
2234c2c66affSColin Finck return IMultiLanguage3_ConvertStringFromUnicode(&This->IMultiLanguage3_iface,
2235c2c66affSColin Finck mode, encoding, src, src_size, dest, dest_size);
2236c2c66affSColin Finck }
2237c2c66affSColin Finck
fnIMultiLanguage_ConvertStringReset(IMultiLanguage * iface)2238c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_ConvertStringReset(
2239c2c66affSColin Finck IMultiLanguage* iface)
2240c2c66affSColin Finck {
2241c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2242c2c66affSColin Finck return IMultiLanguage3_ConvertStringReset(&This->IMultiLanguage3_iface);
2243c2c66affSColin Finck }
2244c2c66affSColin Finck
fnIMultiLanguage_GetRfc1766FromLcid(IMultiLanguage * iface,LCID lcid,BSTR * pbstrRfc1766)2245c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetRfc1766FromLcid(
2246c2c66affSColin Finck IMultiLanguage* iface,
2247c2c66affSColin Finck LCID lcid,
2248c2c66affSColin Finck BSTR* pbstrRfc1766)
2249c2c66affSColin Finck {
2250c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage(iface);
2251c2c66affSColin Finck return IMultiLanguage3_GetRfc1766FromLcid(&This->IMultiLanguage3_iface, lcid, pbstrRfc1766);
2252c2c66affSColin Finck }
2253c2c66affSColin Finck
fnIMultiLanguage_GetLcidFromRfc1766(IMultiLanguage * iface,LCID * locale,BSTR rfc1766)2254c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetLcidFromRfc1766(
2255c2c66affSColin Finck IMultiLanguage* iface,
2256c2c66affSColin Finck LCID* locale,
2257c2c66affSColin Finck BSTR rfc1766)
2258c2c66affSColin Finck {
2259c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage(iface);
2260c2c66affSColin Finck return IMultiLanguage3_GetLcidFromRfc1766(&This->IMultiLanguage3_iface, locale, rfc1766);
2261c2c66affSColin Finck }
2262c2c66affSColin Finck
2263c2c66affSColin Finck /******************************************************************************/
2264c2c66affSColin Finck
2265c2c66affSColin Finck typedef struct tagEnumRfc1766_impl
2266c2c66affSColin Finck {
2267c2c66affSColin Finck IEnumRfc1766 IEnumRfc1766_iface;
2268c2c66affSColin Finck LONG ref;
2269c2c66affSColin Finck RFC1766INFO *info;
2270c2c66affSColin Finck DWORD total, pos;
2271c2c66affSColin Finck } EnumRfc1766_impl;
2272c2c66affSColin Finck
impl_from_IEnumRfc1766(IEnumRfc1766 * iface)2273c2c66affSColin Finck static inline EnumRfc1766_impl *impl_from_IEnumRfc1766( IEnumRfc1766 *iface )
2274c2c66affSColin Finck {
2275c2c66affSColin Finck return CONTAINING_RECORD( iface, EnumRfc1766_impl, IEnumRfc1766_iface );
2276c2c66affSColin Finck }
2277c2c66affSColin Finck
fnIEnumRfc1766_QueryInterface(IEnumRfc1766 * iface,REFIID riid,void ** ppvObject)2278c2c66affSColin Finck static HRESULT WINAPI fnIEnumRfc1766_QueryInterface(
2279c2c66affSColin Finck IEnumRfc1766 *iface,
2280c2c66affSColin Finck REFIID riid,
2281c2c66affSColin Finck void** ppvObject)
2282c2c66affSColin Finck {
2283c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2284c2c66affSColin Finck
2285c2c66affSColin Finck TRACE("%p -> %s\n", This, debugstr_guid(riid) );
2286c2c66affSColin Finck
2287c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown)
2288c2c66affSColin Finck || IsEqualGUID(riid, &IID_IEnumRfc1766))
2289c2c66affSColin Finck {
2290c2c66affSColin Finck IEnumRfc1766_AddRef(iface);
2291c2c66affSColin Finck TRACE("Returning IID_IEnumRfc1766 %p ref = %d\n", This, This->ref);
2292c2c66affSColin Finck *ppvObject = &This->IEnumRfc1766_iface;
2293c2c66affSColin Finck return S_OK;
2294c2c66affSColin Finck }
2295c2c66affSColin Finck
2296c2c66affSColin Finck WARN("(%p) -> (%s,%p), not found\n",This,debugstr_guid(riid),ppvObject);
2297c2c66affSColin Finck return E_NOINTERFACE;
2298c2c66affSColin Finck }
2299c2c66affSColin Finck
fnIEnumRfc1766_AddRef(IEnumRfc1766 * iface)2300c2c66affSColin Finck static ULONG WINAPI fnIEnumRfc1766_AddRef(
2301c2c66affSColin Finck IEnumRfc1766 *iface)
2302c2c66affSColin Finck {
2303c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2304c2c66affSColin Finck return InterlockedIncrement(&This->ref);
2305c2c66affSColin Finck }
2306c2c66affSColin Finck
fnIEnumRfc1766_Release(IEnumRfc1766 * iface)2307c2c66affSColin Finck static ULONG WINAPI fnIEnumRfc1766_Release(
2308c2c66affSColin Finck IEnumRfc1766 *iface)
2309c2c66affSColin Finck {
2310c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2311c2c66affSColin Finck ULONG ref = InterlockedDecrement(&This->ref);
2312c2c66affSColin Finck
2313c2c66affSColin Finck TRACE("%p ref = %d\n", This, ref);
2314c2c66affSColin Finck if (ref == 0)
2315c2c66affSColin Finck {
2316c2c66affSColin Finck TRACE("Destroying %p\n", This);
2317c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This->info);
2318c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
2319c2c66affSColin Finck }
2320c2c66affSColin Finck return ref;
2321c2c66affSColin Finck }
2322c2c66affSColin Finck
fnIEnumRfc1766_Clone(IEnumRfc1766 * iface,IEnumRfc1766 ** ppEnum)2323c2c66affSColin Finck static HRESULT WINAPI fnIEnumRfc1766_Clone(
2324c2c66affSColin Finck IEnumRfc1766 *iface,
2325c2c66affSColin Finck IEnumRfc1766 **ppEnum)
2326c2c66affSColin Finck {
2327c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2328c2c66affSColin Finck
2329c2c66affSColin Finck FIXME("%p %p\n", This, ppEnum);
2330c2c66affSColin Finck return E_NOTIMPL;
2331c2c66affSColin Finck }
2332c2c66affSColin Finck
fnIEnumRfc1766_Next(IEnumRfc1766 * iface,ULONG celt,PRFC1766INFO rgelt,ULONG * pceltFetched)2333c2c66affSColin Finck static HRESULT WINAPI fnIEnumRfc1766_Next(
2334c2c66affSColin Finck IEnumRfc1766 *iface,
2335c2c66affSColin Finck ULONG celt,
2336c2c66affSColin Finck PRFC1766INFO rgelt,
2337c2c66affSColin Finck ULONG *pceltFetched)
2338c2c66affSColin Finck {
2339c2c66affSColin Finck ULONG i;
2340c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2341c2c66affSColin Finck
2342c2c66affSColin Finck TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched);
2343c2c66affSColin Finck
2344c2c66affSColin Finck if (!pceltFetched) return S_FALSE;
2345c2c66affSColin Finck *pceltFetched = 0;
2346c2c66affSColin Finck
2347c2c66affSColin Finck if (!rgelt) return S_FALSE;
2348c2c66affSColin Finck
2349c2c66affSColin Finck if (This->pos + celt > This->total)
2350c2c66affSColin Finck celt = This->total - This->pos;
2351c2c66affSColin Finck
2352c2c66affSColin Finck if (!celt) return S_FALSE;
2353c2c66affSColin Finck
2354c2c66affSColin Finck memcpy(rgelt, This->info + This->pos, celt * sizeof(RFC1766INFO));
2355c2c66affSColin Finck *pceltFetched = celt;
2356c2c66affSColin Finck This->pos += celt;
2357c2c66affSColin Finck
2358c2c66affSColin Finck for (i = 0; i < celt; i++)
2359c2c66affSColin Finck {
2360c2c66affSColin Finck TRACE("#%u: %08x %s %s\n",
2361c2c66affSColin Finck i, rgelt[i].lcid,
2362c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszRfc1766),
2363c2c66affSColin Finck wine_dbgstr_w(rgelt[i].wszLocaleName));
2364c2c66affSColin Finck }
2365c2c66affSColin Finck return S_OK;
2366c2c66affSColin Finck }
2367c2c66affSColin Finck
fnIEnumRfc1766_Reset(IEnumRfc1766 * iface)2368c2c66affSColin Finck static HRESULT WINAPI fnIEnumRfc1766_Reset(
2369c2c66affSColin Finck IEnumRfc1766 *iface)
2370c2c66affSColin Finck {
2371c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2372c2c66affSColin Finck
2373c2c66affSColin Finck TRACE("%p\n", This);
2374c2c66affSColin Finck
2375c2c66affSColin Finck This->pos = 0;
2376c2c66affSColin Finck return S_OK;
2377c2c66affSColin Finck }
2378c2c66affSColin Finck
fnIEnumRfc1766_Skip(IEnumRfc1766 * iface,ULONG celt)2379c2c66affSColin Finck static HRESULT WINAPI fnIEnumRfc1766_Skip(
2380c2c66affSColin Finck IEnumRfc1766 *iface,
2381c2c66affSColin Finck ULONG celt)
2382c2c66affSColin Finck {
2383c2c66affSColin Finck EnumRfc1766_impl *This = impl_from_IEnumRfc1766( iface );
2384c2c66affSColin Finck
2385c2c66affSColin Finck TRACE("%p %u\n", This, celt);
2386c2c66affSColin Finck
2387c2c66affSColin Finck if (celt >= This->total) return S_FALSE;
2388c2c66affSColin Finck
2389c2c66affSColin Finck This->pos += celt;
2390c2c66affSColin Finck return S_OK;
2391c2c66affSColin Finck }
2392c2c66affSColin Finck
2393c2c66affSColin Finck static const IEnumRfc1766Vtbl IEnumRfc1766_vtbl =
2394c2c66affSColin Finck {
2395c2c66affSColin Finck fnIEnumRfc1766_QueryInterface,
2396c2c66affSColin Finck fnIEnumRfc1766_AddRef,
2397c2c66affSColin Finck fnIEnumRfc1766_Release,
2398c2c66affSColin Finck fnIEnumRfc1766_Clone,
2399c2c66affSColin Finck fnIEnumRfc1766_Next,
2400c2c66affSColin Finck fnIEnumRfc1766_Reset,
2401c2c66affSColin Finck fnIEnumRfc1766_Skip
2402c2c66affSColin Finck };
2403c2c66affSColin Finck
2404c2c66affSColin Finck struct enum_locales_data
2405c2c66affSColin Finck {
2406c2c66affSColin Finck RFC1766INFO *info;
2407c2c66affSColin Finck DWORD total, allocated;
2408c2c66affSColin Finck };
2409c2c66affSColin Finck
enum_locales_proc(LPWSTR locale)2410c2c66affSColin Finck static BOOL CALLBACK enum_locales_proc(LPWSTR locale)
2411c2c66affSColin Finck {
2412c2c66affSColin Finck WCHAR *end;
2413c2c66affSColin Finck struct enum_locales_data *data = TlsGetValue(MLANG_tls_index);
2414c2c66affSColin Finck RFC1766INFO *info;
2415c2c66affSColin Finck
2416c2c66affSColin Finck TRACE("%s\n", debugstr_w(locale));
2417c2c66affSColin Finck
2418c2c66affSColin Finck if (data->total >= data->allocated)
2419c2c66affSColin Finck {
2420c2c66affSColin Finck data->allocated += 32;
2421c2c66affSColin Finck data->info = HeapReAlloc(GetProcessHeap(), 0, data->info, data->allocated * sizeof(RFC1766INFO));
2422c2c66affSColin Finck if (!data->info) return FALSE;
2423c2c66affSColin Finck }
2424c2c66affSColin Finck
2425c2c66affSColin Finck info = &data->info[data->total];
2426c2c66affSColin Finck
2427853d6414SAmine Khaldi info->lcid = wcstol(locale, &end, 16);
2428c2c66affSColin Finck if (*end) /* invalid number */
2429c2c66affSColin Finck return FALSE;
2430c2c66affSColin Finck
2431c2c66affSColin Finck info->wszRfc1766[0] = 0;
2432c2c66affSColin Finck lcid_to_rfc1766W( info->lcid, info->wszRfc1766, MAX_RFC1766_NAME );
2433c2c66affSColin Finck
2434c2c66affSColin Finck info->wszLocaleName[0] = 0;
2435c2c66affSColin Finck GetLocaleInfoW(info->lcid, LOCALE_SLANGUAGE, info->wszLocaleName, MAX_LOCALE_NAME);
2436c2c66affSColin Finck TRACE("ISO639: %s SLANGUAGE: %s\n", wine_dbgstr_w(info->wszRfc1766), wine_dbgstr_w(info->wszLocaleName));
2437c2c66affSColin Finck
2438c2c66affSColin Finck data->total++;
2439c2c66affSColin Finck
2440c2c66affSColin Finck return TRUE;
2441c2c66affSColin Finck }
2442c2c66affSColin Finck
EnumRfc1766_create(LANGID LangId,IEnumRfc1766 ** ppEnum)2443c2c66affSColin Finck static HRESULT EnumRfc1766_create(LANGID LangId, IEnumRfc1766 **ppEnum)
2444c2c66affSColin Finck {
2445c2c66affSColin Finck EnumRfc1766_impl *rfc;
2446c2c66affSColin Finck struct enum_locales_data data;
2447c2c66affSColin Finck
2448c2c66affSColin Finck TRACE("%04x, %p\n", LangId, ppEnum);
2449c2c66affSColin Finck
2450c2c66affSColin Finck rfc = HeapAlloc( GetProcessHeap(), 0, sizeof(EnumRfc1766_impl) );
2451c2c66affSColin Finck rfc->IEnumRfc1766_iface.lpVtbl = &IEnumRfc1766_vtbl;
2452c2c66affSColin Finck rfc->ref = 1;
2453c2c66affSColin Finck rfc->pos = 0;
2454c2c66affSColin Finck rfc->total = 0;
2455c2c66affSColin Finck
2456c2c66affSColin Finck data.total = 0;
2457c2c66affSColin Finck data.allocated = 160;
2458c2c66affSColin Finck data.info = HeapAlloc(GetProcessHeap(), 0, data.allocated * sizeof(RFC1766INFO));
2459c2c66affSColin Finck if (!data.info)
2460c2c66affSColin Finck {
2461c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, rfc);
2462c2c66affSColin Finck return E_OUTOFMEMORY;
2463c2c66affSColin Finck }
2464c2c66affSColin Finck
2465c2c66affSColin Finck TlsSetValue(MLANG_tls_index, &data);
2466c2c66affSColin Finck EnumSystemLocalesW(enum_locales_proc, 0/*LOCALE_SUPPORTED*/);
2467c2c66affSColin Finck TlsSetValue(MLANG_tls_index, NULL);
2468c2c66affSColin Finck
2469c2c66affSColin Finck TRACE("enumerated %d rfc1766 structures\n", data.total);
2470c2c66affSColin Finck
2471c2c66affSColin Finck if (!data.total)
2472c2c66affSColin Finck {
2473c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, data.info);
2474c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, rfc);
2475c2c66affSColin Finck return E_FAIL;
2476c2c66affSColin Finck }
2477c2c66affSColin Finck
2478c2c66affSColin Finck rfc->info = data.info;
2479c2c66affSColin Finck rfc->total = data.total;
2480c2c66affSColin Finck
2481c2c66affSColin Finck *ppEnum = &rfc->IEnumRfc1766_iface;
2482c2c66affSColin Finck return S_OK;
2483c2c66affSColin Finck }
2484c2c66affSColin Finck
fnIMultiLanguage_EnumRfc1766(IMultiLanguage * iface,IEnumRfc1766 ** ppEnumRfc1766)2485c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_EnumRfc1766(
2486c2c66affSColin Finck IMultiLanguage *iface,
2487c2c66affSColin Finck IEnumRfc1766 **ppEnumRfc1766)
2488c2c66affSColin Finck {
2489c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage( iface );
2490c2c66affSColin Finck
2491c2c66affSColin Finck TRACE("%p %p\n", This, ppEnumRfc1766);
2492c2c66affSColin Finck
2493c2c66affSColin Finck return EnumRfc1766_create(0, ppEnumRfc1766);
2494c2c66affSColin Finck }
2495c2c66affSColin Finck
2496c2c66affSColin Finck /******************************************************************************/
2497c2c66affSColin Finck
fnIMultiLanguage_GetRfc1766Info(IMultiLanguage * iface,LCID Locale,PRFC1766INFO pRfc1766Info)2498c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_GetRfc1766Info(
2499c2c66affSColin Finck IMultiLanguage* iface,
2500c2c66affSColin Finck LCID Locale,
2501c2c66affSColin Finck PRFC1766INFO pRfc1766Info)
2502c2c66affSColin Finck {
2503c2c66affSColin Finck LCTYPE type = LOCALE_SLANGUAGE;
2504c2c66affSColin Finck
2505c2c66affSColin Finck TRACE("(%p, 0x%04x, %p)\n", iface, Locale, pRfc1766Info);
2506c2c66affSColin Finck
2507c2c66affSColin Finck if (!pRfc1766Info)
2508c2c66affSColin Finck return E_INVALIDARG;
2509c2c66affSColin Finck
2510c2c66affSColin Finck if ((PRIMARYLANGID(Locale) == LANG_ENGLISH) ||
2511c2c66affSColin Finck (PRIMARYLANGID(Locale) == LANG_CHINESE) ||
2512c2c66affSColin Finck (PRIMARYLANGID(Locale) == LANG_ARABIC)) {
2513c2c66affSColin Finck
2514c2c66affSColin Finck if (!SUBLANGID(Locale))
2515c2c66affSColin Finck type = LOCALE_SENGLANGUAGE; /* suppress country */
2516c2c66affSColin Finck }
2517c2c66affSColin Finck else
2518c2c66affSColin Finck {
2519c2c66affSColin Finck if (!SUBLANGID(Locale)) {
2520c2c66affSColin Finck TRACE("SUBLANGID missing in 0x%04x\n", Locale);
2521c2c66affSColin Finck return E_FAIL;
2522c2c66affSColin Finck }
2523c2c66affSColin Finck }
2524c2c66affSColin Finck
2525c2c66affSColin Finck pRfc1766Info->lcid = Locale;
2526c2c66affSColin Finck pRfc1766Info->wszRfc1766[0] = 0;
2527c2c66affSColin Finck pRfc1766Info->wszLocaleName[0] = 0;
2528c2c66affSColin Finck
2529c2c66affSColin Finck if ((!lcid_to_rfc1766W(Locale, pRfc1766Info->wszRfc1766, MAX_RFC1766_NAME)) &&
2530c2c66affSColin Finck (GetLocaleInfoW(Locale, type, pRfc1766Info->wszLocaleName, MAX_LOCALE_NAME) > 0))
2531c2c66affSColin Finck return S_OK;
2532c2c66affSColin Finck
2533c2c66affSColin Finck /* Locale not supported */
2534c2c66affSColin Finck return E_INVALIDARG;
2535c2c66affSColin Finck }
2536c2c66affSColin Finck
fnIMultiLanguage_CreateConvertCharset(IMultiLanguage * iface,UINT src_cp,UINT dst_cp,DWORD prop,IMLangConvertCharset ** convert_charset)2537c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage_CreateConvertCharset(
2538c2c66affSColin Finck IMultiLanguage* iface,
2539c2c66affSColin Finck UINT src_cp,
2540c2c66affSColin Finck UINT dst_cp,
2541c2c66affSColin Finck DWORD prop,
2542c2c66affSColin Finck IMLangConvertCharset** convert_charset)
2543c2c66affSColin Finck {
2544c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage(iface);
2545c2c66affSColin Finck return IMultiLanguage3_CreateConvertCharset(&This->IMultiLanguage3_iface, src_cp, dst_cp, prop, convert_charset);
2546c2c66affSColin Finck }
2547c2c66affSColin Finck
2548c2c66affSColin Finck static const IMultiLanguageVtbl IMultiLanguage_vtbl =
2549c2c66affSColin Finck {
2550c2c66affSColin Finck fnIMultiLanguage_QueryInterface,
2551c2c66affSColin Finck fnIMultiLanguage_AddRef,
2552c2c66affSColin Finck fnIMultiLanguage_Release,
2553c2c66affSColin Finck fnIMultiLanguage_GetNumberOfCodePageInfo,
2554c2c66affSColin Finck fnIMultiLanguage_GetCodePageInfo,
2555c2c66affSColin Finck fnIMultiLanguage_GetFamilyCodePage,
2556c2c66affSColin Finck fnIMultiLanguage_EnumCodePages,
2557c2c66affSColin Finck fnIMultiLanguage_GetCharsetInfo,
2558c2c66affSColin Finck fnIMultiLanguage_IsConvertible,
2559c2c66affSColin Finck fnIMultiLanguage_ConvertString,
2560c2c66affSColin Finck fnIMultiLanguage_ConvertStringToUnicode,
2561c2c66affSColin Finck fnIMultiLanguage_ConvertStringFromUnicode,
2562c2c66affSColin Finck fnIMultiLanguage_ConvertStringReset,
2563c2c66affSColin Finck fnIMultiLanguage_GetRfc1766FromLcid,
2564c2c66affSColin Finck fnIMultiLanguage_GetLcidFromRfc1766,
2565c2c66affSColin Finck fnIMultiLanguage_EnumRfc1766,
2566c2c66affSColin Finck fnIMultiLanguage_GetRfc1766Info,
2567c2c66affSColin Finck fnIMultiLanguage_CreateConvertCharset,
2568c2c66affSColin Finck };
2569c2c66affSColin Finck
2570c2c66affSColin Finck
2571c2c66affSColin Finck /******************************************************************************/
2572c2c66affSColin Finck
impl_from_IMultiLanguage3(IMultiLanguage3 * iface)2573c2c66affSColin Finck static inline MLang_impl *impl_from_IMultiLanguage3( IMultiLanguage3 *iface )
2574c2c66affSColin Finck {
2575c2c66affSColin Finck return CONTAINING_RECORD( iface, MLang_impl, IMultiLanguage3_iface );
2576c2c66affSColin Finck }
2577c2c66affSColin Finck
fnIMultiLanguage3_QueryInterface(IMultiLanguage3 * iface,REFIID riid,void ** obj)2578c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_QueryInterface(
2579c2c66affSColin Finck IMultiLanguage3* iface,
2580c2c66affSColin Finck REFIID riid,
2581c2c66affSColin Finck void** obj)
2582c2c66affSColin Finck {
2583c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2584c2c66affSColin Finck
2585c2c66affSColin Finck TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
2586c2c66affSColin Finck
2587c2c66affSColin Finck if (IsEqualGUID(riid, &IID_IUnknown) ||
2588c2c66affSColin Finck IsEqualGUID(riid, &IID_IMultiLanguage))
2589c2c66affSColin Finck {
2590c2c66affSColin Finck *obj = &This->IMultiLanguage_iface;
2591c2c66affSColin Finck }
2592c2c66affSColin Finck else if (IsEqualGUID(riid, &IID_IMLangCodePages) ||
2593c2c66affSColin Finck IsEqualGUID(riid, &IID_IMLangFontLink))
2594c2c66affSColin Finck {
2595c2c66affSColin Finck *obj = &This->IMLangFontLink_iface;
2596c2c66affSColin Finck }
2597c2c66affSColin Finck else if (IsEqualGUID(riid, &IID_IMLangFontLink2))
2598c2c66affSColin Finck {
2599c2c66affSColin Finck *obj = &This->IMLangFontLink2_iface;
2600c2c66affSColin Finck }
2601c2c66affSColin Finck else if (IsEqualGUID(riid, &IID_IMultiLanguage2) ||
2602c2c66affSColin Finck IsEqualGUID(riid, &IID_IMultiLanguage3))
2603c2c66affSColin Finck {
2604c2c66affSColin Finck *obj = &This->IMultiLanguage3_iface;
2605c2c66affSColin Finck }
2606c2c66affSColin Finck else if (IsEqualGUID(riid, &IID_IMLangLineBreakConsole))
2607c2c66affSColin Finck {
2608c2c66affSColin Finck *obj = &This->IMLangLineBreakConsole_iface;
2609c2c66affSColin Finck }
2610c2c66affSColin Finck else
2611c2c66affSColin Finck {
2612c2c66affSColin Finck WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), obj);
2613c2c66affSColin Finck *obj = NULL;
2614c2c66affSColin Finck return E_NOINTERFACE;
2615c2c66affSColin Finck }
2616c2c66affSColin Finck
2617c2c66affSColin Finck IMultiLanguage3_AddRef(iface);
2618c2c66affSColin Finck return S_OK;
2619c2c66affSColin Finck }
2620c2c66affSColin Finck
fnIMultiLanguage3_AddRef(IMultiLanguage3 * iface)2621c2c66affSColin Finck static ULONG WINAPI fnIMultiLanguage3_AddRef( IMultiLanguage3* iface )
2622c2c66affSColin Finck {
2623c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2624c2c66affSColin Finck return InterlockedIncrement(&This->ref);
2625c2c66affSColin Finck }
2626c2c66affSColin Finck
fnIMultiLanguage3_Release(IMultiLanguage3 * iface)2627c2c66affSColin Finck static ULONG WINAPI fnIMultiLanguage3_Release( IMultiLanguage3* iface )
2628c2c66affSColin Finck {
2629c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2630c2c66affSColin Finck ULONG ref = InterlockedDecrement(&This->ref);
2631c2c66affSColin Finck
2632c2c66affSColin Finck TRACE("(%p)->(%d)\n", This, ref);
2633c2c66affSColin Finck if (ref == 0)
2634c2c66affSColin Finck {
2635c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
2636c2c66affSColin Finck UnlockModule();
2637c2c66affSColin Finck }
2638c2c66affSColin Finck
2639c2c66affSColin Finck return ref;
2640c2c66affSColin Finck }
2641c2c66affSColin Finck
fnIMultiLanguage3_GetNumberOfCodePageInfo(IMultiLanguage3 * iface,UINT * pcCodePage)2642c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetNumberOfCodePageInfo(
2643c2c66affSColin Finck IMultiLanguage3* iface,
2644c2c66affSColin Finck UINT* pcCodePage)
2645c2c66affSColin Finck {
2646c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2647c2c66affSColin Finck
2648c2c66affSColin Finck TRACE("%p, %p\n", This, pcCodePage);
2649c2c66affSColin Finck
2650c2c66affSColin Finck if (!pcCodePage) return E_INVALIDARG;
2651c2c66affSColin Finck
2652c2c66affSColin Finck *pcCodePage = This->total_cp;
2653c2c66affSColin Finck return S_OK;
2654c2c66affSColin Finck }
2655c2c66affSColin Finck
fill_cp_info(const struct mlang_data * ml_data,UINT index,MIMECPINFO * mime_cp_info)2656c2c66affSColin Finck static void fill_cp_info(const struct mlang_data *ml_data, UINT index, MIMECPINFO *mime_cp_info)
2657c2c66affSColin Finck {
2658c2c66affSColin Finck CHARSETINFO csi;
2659c2c66affSColin Finck
2660c2c66affSColin Finck if (TranslateCharsetInfo((DWORD*)(DWORD_PTR)ml_data->family_codepage, &csi,
2661c2c66affSColin Finck TCI_SRCCODEPAGE))
2662c2c66affSColin Finck mime_cp_info->bGDICharset = csi.ciCharset;
2663c2c66affSColin Finck else
2664c2c66affSColin Finck mime_cp_info->bGDICharset = DEFAULT_CHARSET;
2665c2c66affSColin Finck
2666c2c66affSColin Finck mime_cp_info->dwFlags = ml_data->mime_cp_info[index].flags;
2667c2c66affSColin Finck mime_cp_info->uiCodePage = ml_data->mime_cp_info[index].cp;
2668c2c66affSColin Finck mime_cp_info->uiFamilyCodePage = ml_data->family_codepage;
2669c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].description, -1,
2670ccc3eeaeSAmine Khaldi mime_cp_info->wszDescription, ARRAY_SIZE(mime_cp_info->wszDescription));
2671c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].web_charset, -1,
2672ccc3eeaeSAmine Khaldi mime_cp_info->wszWebCharset, ARRAY_SIZE(mime_cp_info->wszWebCharset));
2673c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].header_charset, -1,
2674ccc3eeaeSAmine Khaldi mime_cp_info->wszHeaderCharset, ARRAY_SIZE(mime_cp_info->wszHeaderCharset));
2675c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, ml_data->mime_cp_info[index].body_charset, -1,
2676ccc3eeaeSAmine Khaldi mime_cp_info->wszBodyCharset, ARRAY_SIZE(mime_cp_info->wszBodyCharset));
2677c2c66affSColin Finck
2678c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, ml_data->fixed_font, -1,
2679ccc3eeaeSAmine Khaldi mime_cp_info->wszFixedWidthFont, ARRAY_SIZE(mime_cp_info->wszFixedWidthFont));
2680c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, ml_data->proportional_font, -1,
2681ccc3eeaeSAmine Khaldi mime_cp_info->wszProportionalFont, ARRAY_SIZE(mime_cp_info->wszProportionalFont));
2682c2c66affSColin Finck
2683c2c66affSColin Finck TRACE("%08x %u %u %s %s %s %s %s %s %d\n",
2684c2c66affSColin Finck mime_cp_info->dwFlags, mime_cp_info->uiCodePage,
2685c2c66affSColin Finck mime_cp_info->uiFamilyCodePage,
2686c2c66affSColin Finck wine_dbgstr_w(mime_cp_info->wszDescription),
2687c2c66affSColin Finck wine_dbgstr_w(mime_cp_info->wszWebCharset),
2688c2c66affSColin Finck wine_dbgstr_w(mime_cp_info->wszHeaderCharset),
2689c2c66affSColin Finck wine_dbgstr_w(mime_cp_info->wszBodyCharset),
2690c2c66affSColin Finck wine_dbgstr_w(mime_cp_info->wszFixedWidthFont),
2691c2c66affSColin Finck wine_dbgstr_w(mime_cp_info->wszProportionalFont),
2692c2c66affSColin Finck mime_cp_info->bGDICharset);
2693c2c66affSColin Finck }
2694c2c66affSColin Finck
fnIMultiLanguage3_GetCodePageInfo(IMultiLanguage3 * iface,UINT uiCodePage,LANGID LangId,PMIMECPINFO pCodePageInfo)2695c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetCodePageInfo(
2696c2c66affSColin Finck IMultiLanguage3* iface,
2697c2c66affSColin Finck UINT uiCodePage,
2698c2c66affSColin Finck LANGID LangId,
2699c2c66affSColin Finck PMIMECPINFO pCodePageInfo)
2700c2c66affSColin Finck {
2701c2c66affSColin Finck UINT i, n;
2702c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2703c2c66affSColin Finck
2704c2c66affSColin Finck TRACE("%p, %u, %04x, %p\n", This, uiCodePage, LangId, pCodePageInfo);
2705c2c66affSColin Finck
2706ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
2707c2c66affSColin Finck {
2708c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
2709c2c66affSColin Finck {
2710c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
2711c2c66affSColin Finck {
2712c2c66affSColin Finck fill_cp_info(&mlang_data[i], n, pCodePageInfo);
2713c2c66affSColin Finck return S_OK;
2714c2c66affSColin Finck }
2715c2c66affSColin Finck }
2716c2c66affSColin Finck }
2717c2c66affSColin Finck
2718c2c66affSColin Finck return S_FALSE;
2719c2c66affSColin Finck }
2720c2c66affSColin Finck
fnIMultiLanguage3_GetFamilyCodePage(IMultiLanguage3 * iface,UINT uiCodePage,UINT * puiFamilyCodePage)2721c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetFamilyCodePage(
2722c2c66affSColin Finck IMultiLanguage3* iface,
2723c2c66affSColin Finck UINT uiCodePage,
2724c2c66affSColin Finck UINT* puiFamilyCodePage)
2725c2c66affSColin Finck {
2726c2c66affSColin Finck return GetFamilyCodePage(uiCodePage, puiFamilyCodePage);
2727c2c66affSColin Finck }
2728c2c66affSColin Finck
fnIMultiLanguage3_EnumCodePages(IMultiLanguage3 * iface,DWORD grfFlags,LANGID LangId,IEnumCodePage ** ppEnumCodePage)2729c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_EnumCodePages(
2730c2c66affSColin Finck IMultiLanguage3* iface,
2731c2c66affSColin Finck DWORD grfFlags,
2732c2c66affSColin Finck LANGID LangId,
2733c2c66affSColin Finck IEnumCodePage** ppEnumCodePage)
2734c2c66affSColin Finck {
2735c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2736c2c66affSColin Finck
2737c2c66affSColin Finck TRACE("%p %08x %04x %p\n", This, grfFlags, LangId, ppEnumCodePage);
2738c2c66affSColin Finck
2739c2c66affSColin Finck return EnumCodePage_create( This, grfFlags, LangId, ppEnumCodePage );
2740c2c66affSColin Finck }
2741c2c66affSColin Finck
fnIMultiLanguage3_GetCharsetInfo(IMultiLanguage3 * iface,BSTR Charset,PMIMECSETINFO pCharsetInfo)2742c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetCharsetInfo(
2743c2c66affSColin Finck IMultiLanguage3* iface,
2744c2c66affSColin Finck BSTR Charset,
2745c2c66affSColin Finck PMIMECSETINFO pCharsetInfo)
2746c2c66affSColin Finck {
2747c2c66affSColin Finck UINT i, n;
2748c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2749c2c66affSColin Finck
2750c2c66affSColin Finck TRACE("%p %s %p\n", This, debugstr_w(Charset), pCharsetInfo);
2751c2c66affSColin Finck
2752c2c66affSColin Finck if (!pCharsetInfo) return E_FAIL;
2753c2c66affSColin Finck
2754ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
2755c2c66affSColin Finck {
2756c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
2757c2c66affSColin Finck {
2758c2c66affSColin Finck WCHAR csetW[MAX_MIMECSET_NAME];
2759c2c66affSColin Finck
2760c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].mime_cp_info[n].web_charset, -1, csetW, MAX_MIMECSET_NAME);
2761c2c66affSColin Finck if (!lstrcmpiW(Charset, csetW))
2762c2c66affSColin Finck {
2763c2c66affSColin Finck pCharsetInfo->uiCodePage = mlang_data[i].family_codepage;
2764c2c66affSColin Finck pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp;
2765853d6414SAmine Khaldi lstrcpyW(pCharsetInfo->wszCharset, csetW);
2766c2c66affSColin Finck return S_OK;
2767c2c66affSColin Finck }
2768c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].alias && !lstrcmpiW(Charset, mlang_data[i].mime_cp_info[n].alias))
2769c2c66affSColin Finck {
2770c2c66affSColin Finck pCharsetInfo->uiCodePage = mlang_data[i].family_codepage;
2771c2c66affSColin Finck pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp;
2772853d6414SAmine Khaldi lstrcpyW(pCharsetInfo->wszCharset, mlang_data[i].mime_cp_info[n].alias);
2773c2c66affSColin Finck return S_OK;
2774c2c66affSColin Finck }
2775c2c66affSColin Finck }
2776c2c66affSColin Finck }
2777c2c66affSColin Finck
2778c2c66affSColin Finck /* FIXME:
2779c2c66affSColin Finck * Since we do not support charsets like iso-2022-jp and do not have
2780c2c66affSColin Finck * them in our database as a primary (web_charset) encoding this loop
2781c2c66affSColin Finck * does an attempt to 'approximate' charset name by header_charset.
2782c2c66affSColin Finck */
2783ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
2784c2c66affSColin Finck {
2785c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
2786c2c66affSColin Finck {
2787c2c66affSColin Finck WCHAR csetW[MAX_MIMECSET_NAME];
2788c2c66affSColin Finck
2789c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].mime_cp_info[n].header_charset, -1, csetW, MAX_MIMECSET_NAME);
2790c2c66affSColin Finck if (!lstrcmpiW(Charset, csetW))
2791c2c66affSColin Finck {
2792c2c66affSColin Finck pCharsetInfo->uiCodePage = mlang_data[i].family_codepage;
2793c2c66affSColin Finck pCharsetInfo->uiInternetEncoding = mlang_data[i].mime_cp_info[n].cp;
2794853d6414SAmine Khaldi lstrcpyW(pCharsetInfo->wszCharset, csetW);
2795c2c66affSColin Finck return S_OK;
2796c2c66affSColin Finck }
2797c2c66affSColin Finck }
2798c2c66affSColin Finck }
2799c2c66affSColin Finck
2800c2c66affSColin Finck return E_FAIL;
2801c2c66affSColin Finck }
2802c2c66affSColin Finck
fnIMultiLanguage3_IsConvertible(IMultiLanguage3 * iface,DWORD dwSrcEncoding,DWORD dwDstEncoding)2803c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_IsConvertible(
2804c2c66affSColin Finck IMultiLanguage3* iface,
2805c2c66affSColin Finck DWORD dwSrcEncoding,
2806c2c66affSColin Finck DWORD dwDstEncoding)
2807c2c66affSColin Finck {
2808c2c66affSColin Finck return IsConvertINetStringAvailable(dwSrcEncoding, dwDstEncoding);
2809c2c66affSColin Finck }
2810c2c66affSColin Finck
fnIMultiLanguage3_ConvertString(IMultiLanguage3 * iface,DWORD * pdwMode,DWORD dwSrcEncoding,DWORD dwDstEncoding,BYTE * pSrcStr,UINT * pcSrcSize,BYTE * pDstStr,UINT * pcDstSize)2811c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertString(
2812c2c66affSColin Finck IMultiLanguage3* iface,
2813c2c66affSColin Finck DWORD* pdwMode,
2814c2c66affSColin Finck DWORD dwSrcEncoding,
2815c2c66affSColin Finck DWORD dwDstEncoding,
2816c2c66affSColin Finck BYTE* pSrcStr,
2817c2c66affSColin Finck UINT* pcSrcSize,
2818c2c66affSColin Finck BYTE* pDstStr,
2819c2c66affSColin Finck UINT* pcDstSize)
2820c2c66affSColin Finck {
2821c2c66affSColin Finck return ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding,
2822c2c66affSColin Finck (LPCSTR)pSrcStr, (LPINT)pcSrcSize, (LPSTR)pDstStr, (LPINT)pcDstSize);
2823c2c66affSColin Finck }
2824c2c66affSColin Finck
fnIMultiLanguage3_ConvertStringToUnicode(IMultiLanguage3 * iface,DWORD * pdwMode,DWORD dwEncoding,CHAR * pSrcStr,UINT * pcSrcSize,WCHAR * pDstStr,UINT * pcDstSize)2825c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertStringToUnicode(
2826c2c66affSColin Finck IMultiLanguage3* iface,
2827c2c66affSColin Finck DWORD* pdwMode,
2828c2c66affSColin Finck DWORD dwEncoding,
2829c2c66affSColin Finck CHAR* pSrcStr,
2830c2c66affSColin Finck UINT* pcSrcSize,
2831c2c66affSColin Finck WCHAR* pDstStr,
2832c2c66affSColin Finck UINT* pcDstSize)
2833c2c66affSColin Finck {
2834c2c66affSColin Finck return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding,
2835c2c66affSColin Finck pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
2836c2c66affSColin Finck }
2837c2c66affSColin Finck
fnIMultiLanguage3_ConvertStringFromUnicode(IMultiLanguage3 * iface,DWORD * pdwMode,DWORD dwEncoding,WCHAR * pSrcStr,UINT * pcSrcSize,CHAR * pDstStr,UINT * pcDstSize)2838c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertStringFromUnicode(
2839c2c66affSColin Finck IMultiLanguage3* iface,
2840c2c66affSColin Finck DWORD* pdwMode,
2841c2c66affSColin Finck DWORD dwEncoding,
2842c2c66affSColin Finck WCHAR* pSrcStr,
2843c2c66affSColin Finck UINT* pcSrcSize,
2844c2c66affSColin Finck CHAR* pDstStr,
2845c2c66affSColin Finck UINT* pcDstSize)
2846c2c66affSColin Finck {
2847c2c66affSColin Finck return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding,
2848c2c66affSColin Finck pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
2849c2c66affSColin Finck }
2850c2c66affSColin Finck
fnIMultiLanguage3_ConvertStringReset(IMultiLanguage3 * iface)2851c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertStringReset(
2852c2c66affSColin Finck IMultiLanguage3* iface)
2853c2c66affSColin Finck {
2854c2c66affSColin Finck FIXME("\n");
2855c2c66affSColin Finck return E_NOTIMPL;
2856c2c66affSColin Finck }
2857c2c66affSColin Finck
fnIMultiLanguage3_GetRfc1766FromLcid(IMultiLanguage3 * iface,LCID lcid,BSTR * pbstrRfc1766)2858c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetRfc1766FromLcid(
2859c2c66affSColin Finck IMultiLanguage3* iface,
2860c2c66affSColin Finck LCID lcid,
2861c2c66affSColin Finck BSTR* pbstrRfc1766)
2862c2c66affSColin Finck {
2863c2c66affSColin Finck WCHAR buf[MAX_RFC1766_NAME];
2864c2c66affSColin Finck
2865c2c66affSColin Finck TRACE("%p %04x %p\n", iface, lcid, pbstrRfc1766);
2866c2c66affSColin Finck if (!pbstrRfc1766)
2867c2c66affSColin Finck return E_INVALIDARG;
2868c2c66affSColin Finck
2869c2c66affSColin Finck if (!lcid_to_rfc1766W( lcid, buf, MAX_RFC1766_NAME ))
2870c2c66affSColin Finck {
2871c2c66affSColin Finck *pbstrRfc1766 = SysAllocString( buf );
2872c2c66affSColin Finck return S_OK;
2873c2c66affSColin Finck }
2874c2c66affSColin Finck return E_FAIL;
2875c2c66affSColin Finck }
2876c2c66affSColin Finck
fnIMultiLanguage3_GetLcidFromRfc1766(IMultiLanguage3 * iface,LCID * pLocale,BSTR bstrRfc1766)2877c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetLcidFromRfc1766(
2878c2c66affSColin Finck IMultiLanguage3* iface,
2879c2c66affSColin Finck LCID* pLocale,
2880c2c66affSColin Finck BSTR bstrRfc1766)
2881c2c66affSColin Finck {
2882c2c66affSColin Finck HRESULT hr;
2883c2c66affSColin Finck IEnumRfc1766 *rfc1766;
2884c2c66affSColin Finck
2885c2c66affSColin Finck TRACE("%p %p %s\n", iface, pLocale, debugstr_w(bstrRfc1766));
2886c2c66affSColin Finck
2887c2c66affSColin Finck if (!pLocale || !bstrRfc1766)
2888c2c66affSColin Finck return E_INVALIDARG;
2889c2c66affSColin Finck
2890c2c66affSColin Finck hr = IMultiLanguage3_EnumRfc1766(iface, 0, &rfc1766);
2891c2c66affSColin Finck if (FAILED(hr))
2892c2c66affSColin Finck return hr;
2893c2c66affSColin Finck
2894c2c66affSColin Finck hr = lcid_from_rfc1766(rfc1766, pLocale, bstrRfc1766);
2895c2c66affSColin Finck
2896c2c66affSColin Finck IEnumRfc1766_Release(rfc1766);
2897c2c66affSColin Finck return hr;
2898c2c66affSColin Finck }
2899c2c66affSColin Finck
fnIMultiLanguage3_EnumRfc1766(IMultiLanguage3 * iface,LANGID LangId,IEnumRfc1766 ** ppEnumRfc1766)2900c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_EnumRfc1766(
2901c2c66affSColin Finck IMultiLanguage3* iface,
2902c2c66affSColin Finck LANGID LangId,
2903c2c66affSColin Finck IEnumRfc1766** ppEnumRfc1766)
2904c2c66affSColin Finck {
2905c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
2906c2c66affSColin Finck
2907c2c66affSColin Finck TRACE("%p %p\n", This, ppEnumRfc1766);
2908c2c66affSColin Finck
2909c2c66affSColin Finck return EnumRfc1766_create(LangId, ppEnumRfc1766);
2910c2c66affSColin Finck }
2911c2c66affSColin Finck
fnIMultiLanguage3_GetRfc1766Info(IMultiLanguage3 * iface,LCID Locale,LANGID LangId,PRFC1766INFO pRfc1766Info)2912c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetRfc1766Info(
2913c2c66affSColin Finck IMultiLanguage3* iface,
2914c2c66affSColin Finck LCID Locale,
2915c2c66affSColin Finck LANGID LangId,
2916c2c66affSColin Finck PRFC1766INFO pRfc1766Info)
2917c2c66affSColin Finck {
2918c2c66affSColin Finck static LANGID last_lang = -1;
2919c2c66affSColin Finck LCTYPE type = LOCALE_SLANGUAGE;
2920c2c66affSColin Finck
2921c2c66affSColin Finck TRACE("(%p, 0x%04x, 0x%04x, %p)\n", iface, Locale, LangId, pRfc1766Info);
2922c2c66affSColin Finck
2923c2c66affSColin Finck if (!pRfc1766Info)
2924c2c66affSColin Finck return E_INVALIDARG;
2925c2c66affSColin Finck
2926c2c66affSColin Finck if ((PRIMARYLANGID(Locale) == LANG_ENGLISH) ||
2927c2c66affSColin Finck (PRIMARYLANGID(Locale) == LANG_CHINESE) ||
2928c2c66affSColin Finck (PRIMARYLANGID(Locale) == LANG_ARABIC)) {
2929c2c66affSColin Finck
2930c2c66affSColin Finck if (!SUBLANGID(Locale))
2931c2c66affSColin Finck type = LOCALE_SENGLANGUAGE; /* suppress country */
2932c2c66affSColin Finck }
2933c2c66affSColin Finck else
2934c2c66affSColin Finck {
2935c2c66affSColin Finck if (!SUBLANGID(Locale)) {
2936c2c66affSColin Finck TRACE("SUBLANGID missing in 0x%04x\n", Locale);
2937c2c66affSColin Finck return E_FAIL;
2938c2c66affSColin Finck }
2939c2c66affSColin Finck }
2940c2c66affSColin Finck
2941c2c66affSColin Finck pRfc1766Info->lcid = Locale;
2942c2c66affSColin Finck pRfc1766Info->wszRfc1766[0] = 0;
2943c2c66affSColin Finck pRfc1766Info->wszLocaleName[0] = 0;
2944c2c66affSColin Finck
2945c2c66affSColin Finck if ((PRIMARYLANGID(LangId) != LANG_ENGLISH) &&
2946c2c66affSColin Finck (last_lang != LangId)) {
2947c2c66affSColin Finck FIXME("Only English names supported (requested: 0x%04x)\n", LangId);
2948c2c66affSColin Finck last_lang = LangId;
2949c2c66affSColin Finck }
2950c2c66affSColin Finck
2951c2c66affSColin Finck if ((!lcid_to_rfc1766W(Locale, pRfc1766Info->wszRfc1766, MAX_RFC1766_NAME)) &&
2952c2c66affSColin Finck (GetLocaleInfoW(Locale, type, pRfc1766Info->wszLocaleName, MAX_LOCALE_NAME) > 0))
2953c2c66affSColin Finck return S_OK;
2954c2c66affSColin Finck
2955c2c66affSColin Finck /* Locale not supported */
2956c2c66affSColin Finck return E_INVALIDARG;
2957c2c66affSColin Finck }
2958c2c66affSColin Finck
fnIMultiLanguage3_CreateConvertCharset(IMultiLanguage3 * iface,UINT src_cp,UINT dst_cp,DWORD prop,IMLangConvertCharset ** convert_charset)2959c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_CreateConvertCharset(
2960c2c66affSColin Finck IMultiLanguage3* iface,
2961c2c66affSColin Finck UINT src_cp,
2962c2c66affSColin Finck UINT dst_cp,
2963c2c66affSColin Finck DWORD prop,
2964c2c66affSColin Finck IMLangConvertCharset** convert_charset)
2965c2c66affSColin Finck {
2966c2c66affSColin Finck HRESULT hr;
2967c2c66affSColin Finck
2968c2c66affSColin Finck TRACE("(%u %u 0x%08x %p)\n", src_cp, dst_cp, prop, convert_charset);
2969c2c66affSColin Finck
2970c2c66affSColin Finck hr = MLangConvertCharset_create(NULL, (void**)convert_charset);
2971c2c66affSColin Finck if (FAILED(hr)) return hr;
2972c2c66affSColin Finck
2973c2c66affSColin Finck return IMLangConvertCharset_Initialize(*convert_charset, src_cp, dst_cp, prop);
2974c2c66affSColin Finck }
2975c2c66affSColin Finck
fnIMultiLanguage3_ConvertStringInIStream(IMultiLanguage3 * iface,DWORD * pdwMode,DWORD dwFlag,WCHAR * lpFallBack,DWORD dwSrcEncoding,DWORD dwDstEncoding,IStream * pstmIn,IStream * pstmOut)2976c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertStringInIStream(
2977c2c66affSColin Finck IMultiLanguage3* iface,
2978c2c66affSColin Finck DWORD* pdwMode,
2979c2c66affSColin Finck DWORD dwFlag,
2980c2c66affSColin Finck WCHAR* lpFallBack,
2981c2c66affSColin Finck DWORD dwSrcEncoding,
2982c2c66affSColin Finck DWORD dwDstEncoding,
2983c2c66affSColin Finck IStream* pstmIn,
2984c2c66affSColin Finck IStream* pstmOut)
2985c2c66affSColin Finck {
2986c2c66affSColin Finck char *src, *dst = NULL;
2987c2c66affSColin Finck INT srclen, dstlen;
2988c2c66affSColin Finck STATSTG stat;
2989c2c66affSColin Finck HRESULT hr;
2990c2c66affSColin Finck
2991c2c66affSColin Finck TRACE("%p %0x8 %s %u %u %p %p\n",
2992c2c66affSColin Finck pdwMode, dwFlag, debugstr_w(lpFallBack), dwSrcEncoding, dwDstEncoding, pstmIn, pstmOut);
2993c2c66affSColin Finck
2994c2c66affSColin Finck FIXME("dwFlag and lpFallBack not handled\n");
2995c2c66affSColin Finck
2996c2c66affSColin Finck hr = IStream_Stat(pstmIn, &stat, STATFLAG_NONAME);
2997c2c66affSColin Finck if (FAILED(hr)) return hr;
2998c2c66affSColin Finck
2999c2c66affSColin Finck if (stat.cbSize.QuadPart > MAXLONG) return E_INVALIDARG;
3000c2c66affSColin Finck if (!(src = HeapAlloc(GetProcessHeap(), 0, stat.cbSize.QuadPart))) return E_OUTOFMEMORY;
3001c2c66affSColin Finck
3002c2c66affSColin Finck hr = IStream_Read(pstmIn, src, stat.cbSize.QuadPart, (ULONG *)&srclen);
3003c2c66affSColin Finck if (FAILED(hr)) goto exit;
3004c2c66affSColin Finck
3005c2c66affSColin Finck hr = ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding, src, &srclen, NULL, &dstlen);
3006c2c66affSColin Finck if (FAILED(hr)) goto exit;
3007c2c66affSColin Finck
3008c2c66affSColin Finck if (!(dst = HeapAlloc(GetProcessHeap(), 0, dstlen)))
3009c2c66affSColin Finck {
3010c2c66affSColin Finck hr = E_OUTOFMEMORY;
3011c2c66affSColin Finck goto exit;
3012c2c66affSColin Finck }
3013c2c66affSColin Finck hr = ConvertINetString(pdwMode, dwSrcEncoding, dwDstEncoding, src, &srclen, dst, &dstlen);
3014c2c66affSColin Finck if (FAILED(hr)) goto exit;
3015c2c66affSColin Finck
3016c2c66affSColin Finck hr = IStream_Write(pstmOut, dst, dstlen, NULL);
3017c2c66affSColin Finck
3018c2c66affSColin Finck exit:
3019c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, src);
3020c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, dst);
3021c2c66affSColin Finck return hr;
3022c2c66affSColin Finck }
3023c2c66affSColin Finck
fnIMultiLanguage3_ConvertStringToUnicodeEx(IMultiLanguage3 * iface,DWORD * pdwMode,DWORD dwEncoding,CHAR * pSrcStr,UINT * pcSrcSize,WCHAR * pDstStr,UINT * pcDstSize,DWORD dwFlag,WCHAR * lpFallBack)3024c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertStringToUnicodeEx(
3025c2c66affSColin Finck IMultiLanguage3* iface,
3026c2c66affSColin Finck DWORD* pdwMode,
3027c2c66affSColin Finck DWORD dwEncoding,
3028c2c66affSColin Finck CHAR* pSrcStr,
3029c2c66affSColin Finck UINT* pcSrcSize,
3030c2c66affSColin Finck WCHAR* pDstStr,
3031c2c66affSColin Finck UINT* pcDstSize,
3032c2c66affSColin Finck DWORD dwFlag,
3033c2c66affSColin Finck WCHAR* lpFallBack)
3034c2c66affSColin Finck {
3035c2c66affSColin Finck if (dwFlag || lpFallBack)
3036c2c66affSColin Finck FIXME("Ignoring dwFlag (0x%x/%d) and lpFallBack (%p)\n",
3037c2c66affSColin Finck dwFlag, dwFlag, lpFallBack);
3038c2c66affSColin Finck
3039c2c66affSColin Finck return ConvertINetMultiByteToUnicode(pdwMode, dwEncoding,
3040c2c66affSColin Finck pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
3041c2c66affSColin Finck }
3042c2c66affSColin Finck
3043c2c66affSColin Finck /*****************************************************************************
3044c2c66affSColin Finck * MultiLanguage2::ConvertStringToUnicodeEx
3045c2c66affSColin Finck *
3046c2c66affSColin Finck * Translates the multibyte string from the specified code page to Unicode.
3047c2c66affSColin Finck *
3048c2c66affSColin Finck * PARAMS
3049c2c66affSColin Finck * see ConvertStringToUnicode
3050c2c66affSColin Finck * dwFlag
3051c2c66affSColin Finck * lpFallBack if dwFlag contains MLCONVCHARF_USEDEFCHAR, lpFallBack string used
3052c2c66affSColin Finck * instead unconvertible characters.
3053c2c66affSColin Finck *
3054c2c66affSColin Finck * RETURNS
3055c2c66affSColin Finck * S_OK Success.
3056c2c66affSColin Finck * S_FALSE The conversion is not supported.
3057c2c66affSColin Finck * E_FAIL Some error has occurred.
3058c2c66affSColin Finck *
3059c2c66affSColin Finck * TODO: handle dwFlag and lpFallBack
3060c2c66affSColin Finck */
fnIMultiLanguage3_ConvertStringFromUnicodeEx(IMultiLanguage3 * This,DWORD * pdwMode,DWORD dwEncoding,WCHAR * pSrcStr,UINT * pcSrcSize,CHAR * pDstStr,UINT * pcDstSize,DWORD dwFlag,WCHAR * lpFallBack)3061c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ConvertStringFromUnicodeEx(
3062c2c66affSColin Finck IMultiLanguage3* This,
3063c2c66affSColin Finck DWORD* pdwMode,
3064c2c66affSColin Finck DWORD dwEncoding,
3065c2c66affSColin Finck WCHAR* pSrcStr,
3066c2c66affSColin Finck UINT* pcSrcSize,
3067c2c66affSColin Finck CHAR* pDstStr,
3068c2c66affSColin Finck UINT* pcDstSize,
3069c2c66affSColin Finck DWORD dwFlag,
3070c2c66affSColin Finck WCHAR* lpFallBack)
3071c2c66affSColin Finck {
3072c2c66affSColin Finck FIXME("\n");
3073c2c66affSColin Finck return ConvertINetUnicodeToMultiByte(pdwMode, dwEncoding,
3074c2c66affSColin Finck pSrcStr, (LPINT)pcSrcSize, pDstStr, (LPINT)pcDstSize);
3075c2c66affSColin Finck }
3076c2c66affSColin Finck
fnIMultiLanguage3_DetectCodepageInIStream(IMultiLanguage3 * iface,DWORD dwFlag,DWORD dwPrefWinCodePage,IStream * pstmIn,DetectEncodingInfo * lpEncoding,INT * pnScores)3077c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_DetectCodepageInIStream(
3078c2c66affSColin Finck IMultiLanguage3* iface,
3079c2c66affSColin Finck DWORD dwFlag,
3080c2c66affSColin Finck DWORD dwPrefWinCodePage,
3081c2c66affSColin Finck IStream* pstmIn,
3082c2c66affSColin Finck DetectEncodingInfo* lpEncoding,
3083c2c66affSColin Finck INT* pnScores)
3084c2c66affSColin Finck {
3085c2c66affSColin Finck FIXME("\n");
3086c2c66affSColin Finck return E_NOTIMPL;
3087c2c66affSColin Finck }
3088c2c66affSColin Finck
fnIMultiLanguage3_DetectInputCodepage(IMultiLanguage3 * iface,DWORD dwFlag,DWORD dwPrefWinCodePage,CHAR * pSrcStr,INT * pcSrcSize,DetectEncodingInfo * lpEncoding,INT * pnScores)3089c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_DetectInputCodepage(
3090c2c66affSColin Finck IMultiLanguage3* iface,
3091c2c66affSColin Finck DWORD dwFlag,
3092c2c66affSColin Finck DWORD dwPrefWinCodePage,
3093c2c66affSColin Finck CHAR* pSrcStr,
3094c2c66affSColin Finck INT* pcSrcSize,
3095c2c66affSColin Finck DetectEncodingInfo* lpEncoding,
3096c2c66affSColin Finck INT* pnScores)
3097c2c66affSColin Finck {
3098c2c66affSColin Finck FIXME("\n");
3099c2c66affSColin Finck return E_NOTIMPL;
3100c2c66affSColin Finck }
3101c2c66affSColin Finck
fnIMultiLanguage3_ValidateCodePage(IMultiLanguage3 * iface,UINT uiCodePage,HWND hwnd)3102c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ValidateCodePage(
3103c2c66affSColin Finck IMultiLanguage3* iface,
3104c2c66affSColin Finck UINT uiCodePage,
3105c2c66affSColin Finck HWND hwnd)
3106c2c66affSColin Finck {
3107c2c66affSColin Finck return IMultiLanguage3_ValidateCodePageEx(iface,uiCodePage,hwnd,0);
3108c2c66affSColin Finck }
3109c2c66affSColin Finck
fnIMultiLanguage3_GetCodePageDescription(IMultiLanguage3 * iface,UINT uiCodePage,LCID lcid,LPWSTR lpWideCharStr,int cchWideChar)3110c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetCodePageDescription(
3111c2c66affSColin Finck IMultiLanguage3* iface,
3112c2c66affSColin Finck UINT uiCodePage,
3113c2c66affSColin Finck LCID lcid,
3114c2c66affSColin Finck LPWSTR lpWideCharStr,
3115c2c66affSColin Finck int cchWideChar)
3116c2c66affSColin Finck {
3117c2c66affSColin Finck /* Find first instance */
3118c2c66affSColin Finck unsigned int i,n;
3119c2c66affSColin Finck
3120c2c66affSColin Finck TRACE ("%u, %04x, %p, %d\n", uiCodePage, lcid, lpWideCharStr, cchWideChar);
3121ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
3122c2c66affSColin Finck {
3123c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
3124c2c66affSColin Finck {
3125c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
3126c2c66affSColin Finck {
3127c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0,
3128c2c66affSColin Finck mlang_data[i].mime_cp_info[n].description,
3129c2c66affSColin Finck -1, lpWideCharStr, cchWideChar);
3130c2c66affSColin Finck return S_OK;
3131c2c66affSColin Finck }
3132c2c66affSColin Finck }
3133c2c66affSColin Finck }
3134c2c66affSColin Finck
3135c2c66affSColin Finck return S_FALSE;
3136c2c66affSColin Finck }
3137c2c66affSColin Finck
fnIMultiLanguage3_IsCodePageInstallable(IMultiLanguage3 * iface,UINT uiCodePage)3138c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_IsCodePageInstallable(
3139c2c66affSColin Finck IMultiLanguage3* iface,
3140c2c66affSColin Finck UINT uiCodePage)
3141c2c66affSColin Finck {
3142c2c66affSColin Finck TRACE("%u\n", uiCodePage);
3143c2c66affSColin Finck
3144c2c66affSColin Finck /* FIXME: the installable set is usually larger than the set of valid codepages */
3145c2c66affSColin Finck return IMultiLanguage3_ValidateCodePageEx(iface, uiCodePage, NULL, CPIOD_PEEK);
3146c2c66affSColin Finck }
3147c2c66affSColin Finck
fnIMultiLanguage3_SetMimeDBSource(IMultiLanguage3 * iface,MIMECONTF dwSource)3148c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_SetMimeDBSource(
3149c2c66affSColin Finck IMultiLanguage3* iface,
3150c2c66affSColin Finck MIMECONTF dwSource)
3151c2c66affSColin Finck {
3152c2c66affSColin Finck FIXME("0x%08x\n", dwSource);
3153c2c66affSColin Finck return S_OK;
3154c2c66affSColin Finck }
3155c2c66affSColin Finck
fnIMultiLanguage3_GetNumberOfScripts(IMultiLanguage3 * iface,UINT * pnScripts)3156c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_GetNumberOfScripts(
3157c2c66affSColin Finck IMultiLanguage3* iface,
3158c2c66affSColin Finck UINT* pnScripts)
3159c2c66affSColin Finck {
3160c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
3161c2c66affSColin Finck
3162c2c66affSColin Finck TRACE("%p %p\n", This, pnScripts);
3163c2c66affSColin Finck
3164c2c66affSColin Finck if (!pnScripts) return S_FALSE;
3165c2c66affSColin Finck
3166c2c66affSColin Finck *pnScripts = This->total_scripts;
3167c2c66affSColin Finck return S_OK;
3168c2c66affSColin Finck }
3169c2c66affSColin Finck
fnIMultiLanguage3_EnumScripts(IMultiLanguage3 * iface,DWORD dwFlags,LANGID LangId,IEnumScript ** ppEnumScript)3170c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_EnumScripts(
3171c2c66affSColin Finck IMultiLanguage3* iface,
3172c2c66affSColin Finck DWORD dwFlags,
3173c2c66affSColin Finck LANGID LangId,
3174c2c66affSColin Finck IEnumScript** ppEnumScript)
3175c2c66affSColin Finck {
3176c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
3177c2c66affSColin Finck
3178c2c66affSColin Finck TRACE("%p %08x %04x %p\n", This, dwFlags, LangId, ppEnumScript);
3179c2c66affSColin Finck
3180c2c66affSColin Finck return EnumScript_create( This, dwFlags, LangId, ppEnumScript );
3181c2c66affSColin Finck }
3182c2c66affSColin Finck
fnIMultiLanguage3_ValidateCodePageEx(IMultiLanguage3 * iface,UINT uiCodePage,HWND hwnd,DWORD dwfIODControl)3183c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_ValidateCodePageEx(
3184c2c66affSColin Finck IMultiLanguage3* iface,
3185c2c66affSColin Finck UINT uiCodePage,
3186c2c66affSColin Finck HWND hwnd,
3187c2c66affSColin Finck DWORD dwfIODControl)
3188c2c66affSColin Finck {
3189c2c66affSColin Finck unsigned int i;
3190c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
3191c2c66affSColin Finck
3192c2c66affSColin Finck TRACE("%p %u %p %08x\n", This, uiCodePage, hwnd, dwfIODControl);
3193c2c66affSColin Finck
3194c2c66affSColin Finck /* quick check for kernel32 supported code pages */
3195c2c66affSColin Finck if (IsValidCodePage(uiCodePage))
3196c2c66affSColin Finck return S_OK;
3197c2c66affSColin Finck
3198c2c66affSColin Finck /* check for mlang supported code pages */
3199ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
3200c2c66affSColin Finck {
3201c2c66affSColin Finck UINT n;
3202c2c66affSColin Finck for (n = 0; n < mlang_data[i].number_of_cp; n++)
3203c2c66affSColin Finck {
3204c2c66affSColin Finck if (mlang_data[i].mime_cp_info[n].cp == uiCodePage)
3205c2c66affSColin Finck return S_OK;
3206c2c66affSColin Finck }
3207c2c66affSColin Finck }
3208c2c66affSColin Finck
3209c2c66affSColin Finck if (dwfIODControl != CPIOD_PEEK)
3210c2c66affSColin Finck FIXME("Request to install codepage language pack not handled\n");
3211c2c66affSColin Finck
3212c2c66affSColin Finck return S_FALSE;
3213c2c66affSColin Finck }
3214c2c66affSColin Finck
fnIMultiLanguage3_DetectOutboundCodePage(IMultiLanguage3 * iface,DWORD dwFlags,LPCWSTR lpWideCharStr,UINT cchWideChar,UINT * puiPreferredCodePages,UINT nPreferredCodePages,UINT * puiDetectedCodePages,UINT * pnDetectedCodePages,WCHAR * lpSpecialChar)3215c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_DetectOutboundCodePage(
3216c2c66affSColin Finck IMultiLanguage3 *iface,
3217c2c66affSColin Finck DWORD dwFlags,
3218c2c66affSColin Finck LPCWSTR lpWideCharStr,
3219c2c66affSColin Finck UINT cchWideChar,
3220c2c66affSColin Finck UINT *puiPreferredCodePages,
3221c2c66affSColin Finck UINT nPreferredCodePages,
3222c2c66affSColin Finck UINT *puiDetectedCodePages,
3223c2c66affSColin Finck UINT *pnDetectedCodePages,
3224c2c66affSColin Finck WCHAR *lpSpecialChar)
3225c2c66affSColin Finck {
3226c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
3227c2c66affSColin Finck
3228c2c66affSColin Finck FIXME("(%p)->(%08x %s %p %u %p %p(%u) %s)\n", This, dwFlags, debugstr_w(lpWideCharStr),
3229c2c66affSColin Finck puiPreferredCodePages, nPreferredCodePages, puiDetectedCodePages,
3230c2c66affSColin Finck pnDetectedCodePages, pnDetectedCodePages ? *pnDetectedCodePages : 0,
3231c2c66affSColin Finck debugstr_w(lpSpecialChar));
3232c2c66affSColin Finck
3233c2c66affSColin Finck if (!puiDetectedCodePages || !pnDetectedCodePages || !*pnDetectedCodePages)
3234c2c66affSColin Finck return E_INVALIDARG;
3235c2c66affSColin Finck
3236c2c66affSColin Finck puiDetectedCodePages[0] = CP_UTF8;
3237c2c66affSColin Finck *pnDetectedCodePages = 1;
3238c2c66affSColin Finck return S_OK;
3239c2c66affSColin Finck }
3240c2c66affSColin Finck
fnIMultiLanguage3_DetectOutboundCodePageInIStream(IMultiLanguage3 * iface,DWORD dwFlags,IStream * pStrIn,UINT * puiPreferredCodePages,UINT nPreferredCodePages,UINT * puiDetectedCodePages,UINT * pnDetectedCodePages,WCHAR * lpSpecialChar)3241c2c66affSColin Finck static HRESULT WINAPI fnIMultiLanguage3_DetectOutboundCodePageInIStream(
3242c2c66affSColin Finck IMultiLanguage3 *iface,
3243c2c66affSColin Finck DWORD dwFlags,
3244c2c66affSColin Finck IStream *pStrIn,
3245c2c66affSColin Finck UINT *puiPreferredCodePages,
3246c2c66affSColin Finck UINT nPreferredCodePages,
3247c2c66affSColin Finck UINT *puiDetectedCodePages,
3248c2c66affSColin Finck UINT *pnDetectedCodePages,
3249c2c66affSColin Finck WCHAR *lpSpecialChar)
3250c2c66affSColin Finck {
3251c2c66affSColin Finck MLang_impl *This = impl_from_IMultiLanguage3( iface );
3252c2c66affSColin Finck
3253c2c66affSColin Finck FIXME("(%p)->(%08x %p %p %u %p %p(%u) %s)\n", This, dwFlags, pStrIn,
3254c2c66affSColin Finck puiPreferredCodePages, nPreferredCodePages, puiDetectedCodePages,
3255c2c66affSColin Finck pnDetectedCodePages, pnDetectedCodePages ? *pnDetectedCodePages : 0,
3256c2c66affSColin Finck debugstr_w(lpSpecialChar));
3257c2c66affSColin Finck
3258c2c66affSColin Finck if (!puiDetectedCodePages || !pnDetectedCodePages || !*pnDetectedCodePages)
3259c2c66affSColin Finck return E_INVALIDARG;
3260c2c66affSColin Finck
3261c2c66affSColin Finck puiDetectedCodePages[0] = CP_UTF8;
3262c2c66affSColin Finck *pnDetectedCodePages = 1;
3263c2c66affSColin Finck return S_OK;
3264c2c66affSColin Finck }
3265c2c66affSColin Finck
3266c2c66affSColin Finck static const IMultiLanguage3Vtbl IMultiLanguage3_vtbl =
3267c2c66affSColin Finck {
3268c2c66affSColin Finck fnIMultiLanguage3_QueryInterface,
3269c2c66affSColin Finck fnIMultiLanguage3_AddRef,
3270c2c66affSColin Finck fnIMultiLanguage3_Release,
3271c2c66affSColin Finck fnIMultiLanguage3_GetNumberOfCodePageInfo,
3272c2c66affSColin Finck fnIMultiLanguage3_GetCodePageInfo,
3273c2c66affSColin Finck fnIMultiLanguage3_GetFamilyCodePage,
3274c2c66affSColin Finck fnIMultiLanguage3_EnumCodePages,
3275c2c66affSColin Finck fnIMultiLanguage3_GetCharsetInfo,
3276c2c66affSColin Finck fnIMultiLanguage3_IsConvertible,
3277c2c66affSColin Finck fnIMultiLanguage3_ConvertString,
3278c2c66affSColin Finck fnIMultiLanguage3_ConvertStringToUnicode,
3279c2c66affSColin Finck fnIMultiLanguage3_ConvertStringFromUnicode,
3280c2c66affSColin Finck fnIMultiLanguage3_ConvertStringReset,
3281c2c66affSColin Finck fnIMultiLanguage3_GetRfc1766FromLcid,
3282c2c66affSColin Finck fnIMultiLanguage3_GetLcidFromRfc1766,
3283c2c66affSColin Finck fnIMultiLanguage3_EnumRfc1766,
3284c2c66affSColin Finck fnIMultiLanguage3_GetRfc1766Info,
3285c2c66affSColin Finck fnIMultiLanguage3_CreateConvertCharset,
3286c2c66affSColin Finck fnIMultiLanguage3_ConvertStringInIStream,
3287c2c66affSColin Finck fnIMultiLanguage3_ConvertStringToUnicodeEx,
3288c2c66affSColin Finck fnIMultiLanguage3_ConvertStringFromUnicodeEx,
3289c2c66affSColin Finck fnIMultiLanguage3_DetectCodepageInIStream,
3290c2c66affSColin Finck fnIMultiLanguage3_DetectInputCodepage,
3291c2c66affSColin Finck fnIMultiLanguage3_ValidateCodePage,
3292c2c66affSColin Finck fnIMultiLanguage3_GetCodePageDescription,
3293c2c66affSColin Finck fnIMultiLanguage3_IsCodePageInstallable,
3294c2c66affSColin Finck fnIMultiLanguage3_SetMimeDBSource,
3295c2c66affSColin Finck fnIMultiLanguage3_GetNumberOfScripts,
3296c2c66affSColin Finck fnIMultiLanguage3_EnumScripts,
3297c2c66affSColin Finck fnIMultiLanguage3_ValidateCodePageEx,
3298c2c66affSColin Finck fnIMultiLanguage3_DetectOutboundCodePage,
3299c2c66affSColin Finck fnIMultiLanguage3_DetectOutboundCodePageInIStream
3300c2c66affSColin Finck };
3301c2c66affSColin Finck
3302c2c66affSColin Finck /******************************************************************************/
3303c2c66affSColin Finck
impl_from_IMLangFontLink2(IMLangFontLink2 * iface)3304c2c66affSColin Finck static inline MLang_impl *impl_from_IMLangFontLink2( IMLangFontLink2 *iface )
3305c2c66affSColin Finck {
3306c2c66affSColin Finck return CONTAINING_RECORD( iface, MLang_impl, IMLangFontLink2_iface );
3307c2c66affSColin Finck }
3308c2c66affSColin Finck
fnIMLangFontLink2_QueryInterface(IMLangFontLink2 * iface,REFIID riid,void ** ppvObject)3309c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_QueryInterface(
3310c2c66affSColin Finck IMLangFontLink2 * iface,
3311c2c66affSColin Finck REFIID riid,
3312c2c66affSColin Finck void** ppvObject)
3313c2c66affSColin Finck {
3314c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2( iface );
3315c2c66affSColin Finck return IMultiLanguage3_QueryInterface( &This->IMultiLanguage3_iface, riid, ppvObject );
3316c2c66affSColin Finck }
3317c2c66affSColin Finck
fnIMLangFontLink2_AddRef(IMLangFontLink2 * iface)3318c2c66affSColin Finck static ULONG WINAPI fnIMLangFontLink2_AddRef( IMLangFontLink2* iface )
3319c2c66affSColin Finck {
3320c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2( iface );
3321c2c66affSColin Finck return IMultiLanguage3_AddRef( &This->IMultiLanguage3_iface );
3322c2c66affSColin Finck }
3323c2c66affSColin Finck
fnIMLangFontLink2_Release(IMLangFontLink2 * iface)3324c2c66affSColin Finck static ULONG WINAPI fnIMLangFontLink2_Release( IMLangFontLink2* iface )
3325c2c66affSColin Finck {
3326c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2( iface );
3327c2c66affSColin Finck return IMultiLanguage3_Release( &This->IMultiLanguage3_iface );
3328c2c66affSColin Finck }
3329c2c66affSColin Finck
fnIMLangFontLink2_GetCharCodePages(IMLangFontLink2 * iface,WCHAR ch_src,DWORD * ret_codepages)3330c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_GetCharCodePages( IMLangFontLink2* iface,
3331c2c66affSColin Finck WCHAR ch_src, DWORD *ret_codepages)
3332c2c66affSColin Finck {
3333c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2(iface);
3334c2c66affSColin Finck unsigned int i;
3335c2c66affSColin Finck
3336c2c66affSColin Finck TRACE("(%p)->(%s %p)\n", This, debugstr_wn(&ch_src, 1), ret_codepages);
3337c2c66affSColin Finck
3338c2c66affSColin Finck *ret_codepages = 0;
3339c2c66affSColin Finck
3340ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
3341c2c66affSColin Finck {
3342c2c66affSColin Finck BOOL used_dc;
3343c2c66affSColin Finck CHAR buf;
3344c2c66affSColin Finck
3345c2c66affSColin Finck WideCharToMultiByte(mlang_data[i].family_codepage, WC_NO_BEST_FIT_CHARS,
3346c2c66affSColin Finck &ch_src, 1, &buf, 1, NULL, &used_dc);
3347c2c66affSColin Finck
3348c2c66affSColin Finck /* If default char is not used, current codepage include the given symbol */
3349c2c66affSColin Finck if (!used_dc)
3350c2c66affSColin Finck {
3351c2c66affSColin Finck DWORD codepages;
3352c2c66affSColin Finck
3353c2c66affSColin Finck IMLangFontLink2_CodePageToCodePages(iface,
3354c2c66affSColin Finck mlang_data[i].family_codepage, &codepages);
3355c2c66affSColin Finck *ret_codepages |= codepages;
3356c2c66affSColin Finck }
3357c2c66affSColin Finck }
3358c2c66affSColin Finck return S_OK;
3359c2c66affSColin Finck }
3360c2c66affSColin Finck
fnIMLangFontLink2_GetStrCodePages(IMLangFontLink2 * iface,const WCHAR * src,LONG src_len,DWORD priority_cp,DWORD * codepages,LONG * ret_len)3361c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_GetStrCodePages( IMLangFontLink2* iface,
3362c2c66affSColin Finck const WCHAR *src, LONG src_len, DWORD priority_cp,
3363c2c66affSColin Finck DWORD *codepages, LONG *ret_len)
3364c2c66affSColin Finck {
3365c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2(iface);
3366c2c66affSColin Finck LONG i;
3367c2c66affSColin Finck DWORD cps = 0;
3368c2c66affSColin Finck
3369c2c66affSColin Finck TRACE("(%p)->(%s:%d %x %p %p)\n", This, debugstr_wn(src, src_len), src_len, priority_cp,
3370c2c66affSColin Finck codepages, ret_len);
3371c2c66affSColin Finck
3372c2c66affSColin Finck if (codepages) *codepages = 0;
3373c2c66affSColin Finck if (ret_len) *ret_len = 0;
3374c2c66affSColin Finck
3375c2c66affSColin Finck if (!src || !src_len || src_len < 0)
3376c2c66affSColin Finck return E_INVALIDARG;
3377c2c66affSColin Finck
3378c2c66affSColin Finck for (i = 0; i < src_len; i++)
3379c2c66affSColin Finck {
3380c2c66affSColin Finck DWORD cp;
3381c2c66affSColin Finck HRESULT ret;
3382c2c66affSColin Finck
3383c2c66affSColin Finck ret = IMLangFontLink2_GetCharCodePages(iface, src[i], &cp);
3384c2c66affSColin Finck if (ret != S_OK) return E_FAIL;
3385c2c66affSColin Finck
3386c2c66affSColin Finck if (!cps) cps = cp;
3387c2c66affSColin Finck else cps &= cp;
3388c2c66affSColin Finck
3389c2c66affSColin Finck /* FIXME: not tested */
3390c2c66affSColin Finck if (priority_cp & cps) break;
3391c2c66affSColin Finck }
3392c2c66affSColin Finck
3393c2c66affSColin Finck if (codepages) *codepages = cps;
3394c2c66affSColin Finck if (ret_len) *ret_len = min( i + 1, src_len );
3395c2c66affSColin Finck return S_OK;
3396c2c66affSColin Finck }
3397c2c66affSColin Finck
fnIMLangFontLink2_CodePageToCodePages(IMLangFontLink2 * iface,UINT codepage,DWORD * codepages)3398c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_CodePageToCodePages(IMLangFontLink2* iface,
3399c2c66affSColin Finck UINT codepage,
3400c2c66affSColin Finck DWORD *codepages)
3401c2c66affSColin Finck {
3402c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2(iface);
3403c2c66affSColin Finck CHARSETINFO cs;
3404c2c66affSColin Finck BOOL rc;
3405c2c66affSColin Finck
3406c2c66affSColin Finck TRACE("(%p)->(%u %p)\n", This, codepage, codepages);
3407c2c66affSColin Finck
3408c2c66affSColin Finck rc = TranslateCharsetInfo((DWORD*)(DWORD_PTR)codepage, &cs, TCI_SRCCODEPAGE);
3409c2c66affSColin Finck if (rc)
3410c2c66affSColin Finck {
3411c2c66affSColin Finck *codepages = cs.fs.fsCsb[0];
3412c2c66affSColin Finck TRACE("resulting codepages 0x%x\n", *codepages);
3413c2c66affSColin Finck return S_OK;
3414c2c66affSColin Finck }
3415c2c66affSColin Finck
3416c2c66affSColin Finck TRACE("codepage not found\n");
3417c2c66affSColin Finck *codepages = 0;
3418c2c66affSColin Finck return E_FAIL;
3419c2c66affSColin Finck }
3420c2c66affSColin Finck
fnIMLangFontLink2_CodePagesToCodePage(IMLangFontLink2 * iface,DWORD codepages,UINT def_codepage,UINT * codepage)3421c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_CodePagesToCodePage(IMLangFontLink2* iface,
3422c2c66affSColin Finck DWORD codepages, UINT def_codepage, UINT *codepage)
3423c2c66affSColin Finck {
3424c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2(iface);
3425c2c66affSColin Finck DWORD mask = 0;
3426c2c66affSColin Finck CHARSETINFO cs;
3427c2c66affSColin Finck BOOL rc;
3428c2c66affSColin Finck UINT i;
3429c2c66affSColin Finck
3430c2c66affSColin Finck TRACE("(%p)->(0x%x %u %p)\n", This, codepages, def_codepage, codepage);
3431c2c66affSColin Finck
3432c2c66affSColin Finck *codepage = 0;
3433c2c66affSColin Finck
3434c2c66affSColin Finck rc = TranslateCharsetInfo((DWORD*)(DWORD_PTR)def_codepage, &cs, TCI_SRCCODEPAGE);
3435c2c66affSColin Finck if (rc && (codepages & cs.fs.fsCsb[0]))
3436c2c66affSColin Finck {
3437c2c66affSColin Finck TRACE("Found Default Codepage\n");
3438c2c66affSColin Finck *codepage = def_codepage;
3439c2c66affSColin Finck return S_OK;
3440c2c66affSColin Finck }
3441c2c66affSColin Finck
3442c2c66affSColin Finck for (i = 0; i < 32; i++)
3443c2c66affSColin Finck {
3444c2c66affSColin Finck mask = 1 << i;
3445c2c66affSColin Finck if (codepages & mask)
3446c2c66affSColin Finck {
3447c2c66affSColin Finck DWORD Csb[2];
3448c2c66affSColin Finck Csb[0] = mask;
3449c2c66affSColin Finck Csb[1] = 0x0;
3450c2c66affSColin Finck rc = TranslateCharsetInfo(Csb, &cs, TCI_SRCFONTSIG);
3451c2c66affSColin Finck if (!rc)
3452c2c66affSColin Finck continue;
3453c2c66affSColin Finck
3454c2c66affSColin Finck TRACE("Falling back to least significant found CodePage %u\n",
3455c2c66affSColin Finck cs.ciACP);
3456c2c66affSColin Finck *codepage = cs.ciACP;
3457c2c66affSColin Finck return S_OK;
3458c2c66affSColin Finck }
3459c2c66affSColin Finck }
3460c2c66affSColin Finck
3461c2c66affSColin Finck TRACE("no codepage found\n");
3462c2c66affSColin Finck return E_FAIL;
3463c2c66affSColin Finck }
3464c2c66affSColin Finck
fnIMLangFontLink2_GetFontCodePages(IMLangFontLink2 * iface,HDC hdc,HFONT hfont,DWORD * codepages)3465c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_GetFontCodePages(IMLangFontLink2 *iface,
3466c2c66affSColin Finck HDC hdc, HFONT hfont, DWORD *codepages)
3467c2c66affSColin Finck {
3468c2c66affSColin Finck MLang_impl *This = impl_from_IMLangFontLink2(iface);
3469c2c66affSColin Finck FONTSIGNATURE fontsig;
3470c2c66affSColin Finck HFONT old_font;
3471c2c66affSColin Finck
3472c2c66affSColin Finck TRACE("(%p)->(%p %p %p)\n", This, hdc, hfont, codepages);
3473c2c66affSColin Finck
3474c2c66affSColin Finck old_font = SelectObject(hdc, hfont);
3475c2c66affSColin Finck GetTextCharsetInfo(hdc, &fontsig, 0);
3476c2c66affSColin Finck SelectObject(hdc, old_font);
3477c2c66affSColin Finck
3478c2c66affSColin Finck *codepages = fontsig.fsCsb[0];
3479c2c66affSColin Finck TRACE("ret 0x%x\n", fontsig.fsCsb[0]);
3480c2c66affSColin Finck
3481c2c66affSColin Finck return S_OK;
3482c2c66affSColin Finck }
3483c2c66affSColin Finck
fnIMLangFontLink2_ReleaseFont(IMLangFontLink2 * This,HFONT hFont)3484c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_ReleaseFont(IMLangFontLink2* This,
3485c2c66affSColin Finck HFONT hFont)
3486c2c66affSColin Finck {
34875e2c163fSAmine Khaldi TRACE("(%p)->%p\n",This, hFont);
34885e2c163fSAmine Khaldi
34895e2c163fSAmine Khaldi return release_font(hFont);
3490c2c66affSColin Finck }
3491c2c66affSColin Finck
fnIMLangFontLink2_ResetFontMapping(IMLangFontLink2 * This)3492c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_ResetFontMapping(IMLangFontLink2* This)
3493c2c66affSColin Finck {
34945e2c163fSAmine Khaldi TRACE("(%p)\n",This);
34955e2c163fSAmine Khaldi
34965e2c163fSAmine Khaldi return clear_font_cache();
3497c2c66affSColin Finck }
3498c2c66affSColin Finck
fnIMLangFontLink2_MapFont(IMLangFontLink2 * This,HDC hDC,DWORD dwCodePages,WCHAR chSrc,HFONT * pFont)3499c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_MapFont(IMLangFontLink2* This,
3500c2c66affSColin Finck HDC hDC, DWORD dwCodePages, WCHAR chSrc, HFONT *pFont)
3501c2c66affSColin Finck {
35025e2c163fSAmine Khaldi HFONT old_font;
35035e2c163fSAmine Khaldi
35045e2c163fSAmine Khaldi TRACE("(%p)->%p %08x %04x %p\n",This, hDC, dwCodePages, chSrc, pFont);
35055e2c163fSAmine Khaldi
35065e2c163fSAmine Khaldi if (!hDC) return E_FAIL;
35075e2c163fSAmine Khaldi
35085e2c163fSAmine Khaldi if (dwCodePages != 0)
35095e2c163fSAmine Khaldi {
35105e2c163fSAmine Khaldi old_font = GetCurrentObject(hDC, OBJ_FONT);
35115e2c163fSAmine Khaldi return map_font(hDC, dwCodePages, old_font, pFont);
35125e2c163fSAmine Khaldi }
35135e2c163fSAmine Khaldi else
35145e2c163fSAmine Khaldi {
35155e2c163fSAmine Khaldi if (pFont == NULL) return E_INVALIDARG;
35165e2c163fSAmine Khaldi FIXME("the situation where dwCodepages is set to zero is not implemented\n");
35175e2c163fSAmine Khaldi return E_FAIL;
35185e2c163fSAmine Khaldi }
3519c2c66affSColin Finck }
3520c2c66affSColin Finck
fnIMLangFontLink2_GetFontUnicodeRanges(IMLangFontLink2 * This,HDC hDC,UINT * puiRanges,UNICODERANGE * pUranges)3521c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_GetFontUnicodeRanges(IMLangFontLink2* This,
3522c2c66affSColin Finck HDC hDC, UINT *puiRanges, UNICODERANGE *pUranges)
3523c2c66affSColin Finck {
3524c2c66affSColin Finck DWORD size;
3525c2c66affSColin Finck GLYPHSET *gs;
3526c2c66affSColin Finck
3527c2c66affSColin Finck TRACE("(%p)->%p %p %p\n", This, hDC, puiRanges, pUranges);
3528c2c66affSColin Finck
3529c2c66affSColin Finck if (!puiRanges) return E_INVALIDARG;
3530c2c66affSColin Finck if (!(size = GetFontUnicodeRanges(hDC, NULL))) return E_FAIL;
3531c2c66affSColin Finck if (!(gs = HeapAlloc(GetProcessHeap(), 0, size))) return E_OUTOFMEMORY;
3532c2c66affSColin Finck
3533c2c66affSColin Finck GetFontUnicodeRanges(hDC, gs);
3534c2c66affSColin Finck *puiRanges = gs->cRanges;
3535c2c66affSColin Finck if (pUranges)
3536c2c66affSColin Finck {
3537c2c66affSColin Finck UINT i;
3538c2c66affSColin Finck for (i = 0; i < gs->cRanges; i++)
3539c2c66affSColin Finck {
3540c2c66affSColin Finck if (i >= *puiRanges) break;
3541c2c66affSColin Finck pUranges[i].wcFrom = gs->ranges[i].wcLow;
3542c2c66affSColin Finck pUranges[i].wcTo = gs->ranges[i].wcLow + gs->ranges[i].cGlyphs;
3543c2c66affSColin Finck }
3544c2c66affSColin Finck *puiRanges = i;
3545c2c66affSColin Finck }
3546c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, gs);
3547c2c66affSColin Finck return S_OK;
3548c2c66affSColin Finck }
3549c2c66affSColin Finck
fnIMLangFontLink2_GetScriptFontInfo(IMLangFontLink2 * This,SCRIPT_ID sid,DWORD dwFlags,UINT * puiFonts,SCRIPTFONTINFO * pScriptFont)3550c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_GetScriptFontInfo(IMLangFontLink2* This,
3551c2c66affSColin Finck SCRIPT_ID sid, DWORD dwFlags, UINT *puiFonts,
3552c2c66affSColin Finck SCRIPTFONTINFO *pScriptFont)
3553c2c66affSColin Finck {
3554c2c66affSColin Finck UINT i, j;
3555c2c66affSColin Finck
3556c2c66affSColin Finck TRACE("(%p)->%u %x %p %p\n", This, sid, dwFlags, puiFonts, pScriptFont);
3557c2c66affSColin Finck
3558c2c66affSColin Finck if (!dwFlags) dwFlags = SCRIPTCONTF_PROPORTIONAL_FONT;
3559c2c66affSColin Finck
3560ccc3eeaeSAmine Khaldi for (i = 0, j = 0; i < ARRAY_SIZE(mlang_data); i++)
3561c2c66affSColin Finck {
3562c2c66affSColin Finck if (sid == mlang_data[i].sid)
3563c2c66affSColin Finck {
3564c2c66affSColin Finck if (pScriptFont)
3565c2c66affSColin Finck {
3566c2c66affSColin Finck if (j >= *puiFonts) break;
3567c2c66affSColin Finck
3568*be08d69bSSerge Gautherie pScriptFont[j].scripts = (SCRIPT_IDS)1 << mlang_data[i].sid;
3569c2c66affSColin Finck if (dwFlags == SCRIPTCONTF_FIXED_FONT)
3570c2c66affSColin Finck {
3571c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].fixed_font, -1,
3572c2c66affSColin Finck pScriptFont[j].wszFont, MAX_MIMEFACE_NAME);
3573c2c66affSColin Finck }
3574c2c66affSColin Finck else if (dwFlags == SCRIPTCONTF_PROPORTIONAL_FONT)
3575c2c66affSColin Finck {
3576c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, mlang_data[i].proportional_font, -1,
3577c2c66affSColin Finck pScriptFont[j].wszFont, MAX_MIMEFACE_NAME);
3578c2c66affSColin Finck }
3579c2c66affSColin Finck }
3580c2c66affSColin Finck j++;
3581c2c66affSColin Finck }
3582c2c66affSColin Finck }
3583c2c66affSColin Finck *puiFonts = j;
3584c2c66affSColin Finck return S_OK;
3585c2c66affSColin Finck }
3586c2c66affSColin Finck
fnIMLangFontLink2_CodePageToScriptID(IMLangFontLink2 * This,UINT uiCodePage,SCRIPT_ID * pSid)3587c2c66affSColin Finck static HRESULT WINAPI fnIMLangFontLink2_CodePageToScriptID(IMLangFontLink2* This,
3588c2c66affSColin Finck UINT uiCodePage, SCRIPT_ID *pSid)
3589c2c66affSColin Finck {
3590c2c66affSColin Finck UINT i;
3591c2c66affSColin Finck
3592c2c66affSColin Finck TRACE("(%p)->%i %p\n", This, uiCodePage, pSid);
3593c2c66affSColin Finck
3594c2c66affSColin Finck if (uiCodePage == CP_UNICODE) return E_FAIL;
3595c2c66affSColin Finck
3596ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
3597c2c66affSColin Finck {
3598c2c66affSColin Finck if (uiCodePage == mlang_data[i].family_codepage)
3599c2c66affSColin Finck {
3600c2c66affSColin Finck if (pSid) *pSid = mlang_data[i].sid;
3601c2c66affSColin Finck return S_OK;
3602c2c66affSColin Finck }
3603c2c66affSColin Finck }
3604c2c66affSColin Finck return E_FAIL;
3605c2c66affSColin Finck }
3606c2c66affSColin Finck
3607c2c66affSColin Finck static const IMLangFontLink2Vtbl IMLangFontLink2_vtbl =
3608c2c66affSColin Finck {
3609c2c66affSColin Finck fnIMLangFontLink2_QueryInterface,
3610c2c66affSColin Finck fnIMLangFontLink2_AddRef,
3611c2c66affSColin Finck fnIMLangFontLink2_Release,
3612c2c66affSColin Finck fnIMLangFontLink2_GetCharCodePages,
3613c2c66affSColin Finck fnIMLangFontLink2_GetStrCodePages,
3614c2c66affSColin Finck fnIMLangFontLink2_CodePageToCodePages,
3615c2c66affSColin Finck fnIMLangFontLink2_CodePagesToCodePage,
3616c2c66affSColin Finck fnIMLangFontLink2_GetFontCodePages,
3617c2c66affSColin Finck fnIMLangFontLink2_ReleaseFont,
3618c2c66affSColin Finck fnIMLangFontLink2_ResetFontMapping,
3619c2c66affSColin Finck fnIMLangFontLink2_MapFont,
3620c2c66affSColin Finck fnIMLangFontLink2_GetFontUnicodeRanges,
3621c2c66affSColin Finck fnIMLangFontLink2_GetScriptFontInfo,
3622c2c66affSColin Finck fnIMLangFontLink2_CodePageToScriptID
3623c2c66affSColin Finck };
3624c2c66affSColin Finck
3625c2c66affSColin Finck /******************************************************************************/
3626c2c66affSColin Finck
impl_from_IMLangLineBreakConsole(IMLangLineBreakConsole * iface)3627c2c66affSColin Finck static inline MLang_impl *impl_from_IMLangLineBreakConsole( IMLangLineBreakConsole *iface )
3628c2c66affSColin Finck {
3629c2c66affSColin Finck return CONTAINING_RECORD( iface, MLang_impl, IMLangLineBreakConsole_iface );
3630c2c66affSColin Finck }
3631c2c66affSColin Finck
fnIMLangLineBreakConsole_QueryInterface(IMLangLineBreakConsole * iface,REFIID riid,void ** ppvObject)3632c2c66affSColin Finck static HRESULT WINAPI fnIMLangLineBreakConsole_QueryInterface(
3633c2c66affSColin Finck IMLangLineBreakConsole* iface,
3634c2c66affSColin Finck REFIID riid,
3635c2c66affSColin Finck void** ppvObject)
3636c2c66affSColin Finck {
3637c2c66affSColin Finck MLang_impl *This = impl_from_IMLangLineBreakConsole( iface );
3638c2c66affSColin Finck return IMultiLanguage3_QueryInterface( &This->IMultiLanguage3_iface, riid, ppvObject );
3639c2c66affSColin Finck }
3640c2c66affSColin Finck
fnIMLangLineBreakConsole_AddRef(IMLangLineBreakConsole * iface)3641c2c66affSColin Finck static ULONG WINAPI fnIMLangLineBreakConsole_AddRef(
3642c2c66affSColin Finck IMLangLineBreakConsole* iface )
3643c2c66affSColin Finck {
3644c2c66affSColin Finck MLang_impl *This = impl_from_IMLangLineBreakConsole( iface );
3645c2c66affSColin Finck return IMultiLanguage3_AddRef( &This->IMultiLanguage3_iface );
3646c2c66affSColin Finck }
3647c2c66affSColin Finck
fnIMLangLineBreakConsole_Release(IMLangLineBreakConsole * iface)3648c2c66affSColin Finck static ULONG WINAPI fnIMLangLineBreakConsole_Release(
3649c2c66affSColin Finck IMLangLineBreakConsole* iface )
3650c2c66affSColin Finck {
3651c2c66affSColin Finck MLang_impl *This = impl_from_IMLangLineBreakConsole( iface );
3652c2c66affSColin Finck return IMultiLanguage3_Release( &This->IMultiLanguage3_iface );
3653c2c66affSColin Finck }
3654c2c66affSColin Finck
fnIMLangLineBreakConsole_BreakLineML(IMLangLineBreakConsole * iface,IMLangString * pSrcMLStr,LONG lSrcPos,LONG lSrcLen,LONG cMinColumns,LONG cMaxColumns,LONG * plLineLen,LONG * plSkipLen)3655c2c66affSColin Finck static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineML(
3656c2c66affSColin Finck IMLangLineBreakConsole* iface,
3657c2c66affSColin Finck IMLangString* pSrcMLStr,
3658c2c66affSColin Finck LONG lSrcPos,
3659c2c66affSColin Finck LONG lSrcLen,
3660c2c66affSColin Finck LONG cMinColumns,
3661c2c66affSColin Finck LONG cMaxColumns,
3662c2c66affSColin Finck LONG* plLineLen,
3663c2c66affSColin Finck LONG* plSkipLen)
3664c2c66affSColin Finck {
3665c2c66affSColin Finck FIXME("(%p)->%p %i %i %i %i %p %p\n", iface, pSrcMLStr, lSrcPos, lSrcLen, cMinColumns, cMaxColumns, plLineLen, plSkipLen);
3666c2c66affSColin Finck return E_NOTIMPL;
3667c2c66affSColin Finck }
3668c2c66affSColin Finck
fnIMLangLineBreakConsole_BreakLineW(IMLangLineBreakConsole * iface,LCID locale,const WCHAR * pszSrc,LONG cchSrc,LONG cMaxColumns,LONG * pcchLine,LONG * pcchSkip)3669c2c66affSColin Finck static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineW(
3670c2c66affSColin Finck IMLangLineBreakConsole* iface,
3671c2c66affSColin Finck LCID locale,
3672c2c66affSColin Finck const WCHAR* pszSrc,
3673c2c66affSColin Finck LONG cchSrc,
3674c2c66affSColin Finck LONG cMaxColumns,
3675c2c66affSColin Finck LONG* pcchLine,
3676c2c66affSColin Finck LONG* pcchSkip )
3677c2c66affSColin Finck {
3678c2c66affSColin Finck FIXME("(%p)->%i %s %i %i %p %p\n", iface, locale, debugstr_wn(pszSrc,cchSrc), cchSrc, cMaxColumns, pcchLine, pcchSkip);
3679c2c66affSColin Finck
3680c2c66affSColin Finck *pcchLine = cchSrc;
3681c2c66affSColin Finck *pcchSkip = 0;
3682c2c66affSColin Finck return S_OK;
3683c2c66affSColin Finck }
3684c2c66affSColin Finck
fnIMLangLineBreakConsole_BreakLineA(IMLangLineBreakConsole * iface,LCID locale,UINT uCodePage,const CHAR * pszSrc,LONG cchSrc,LONG cMaxColumns,LONG * pcchLine,LONG * pcchSkip)3685c2c66affSColin Finck static HRESULT WINAPI fnIMLangLineBreakConsole_BreakLineA(
3686c2c66affSColin Finck IMLangLineBreakConsole* iface,
3687c2c66affSColin Finck LCID locale,
3688c2c66affSColin Finck UINT uCodePage,
3689c2c66affSColin Finck const CHAR* pszSrc,
3690c2c66affSColin Finck LONG cchSrc,
3691c2c66affSColin Finck LONG cMaxColumns,
3692c2c66affSColin Finck LONG* pcchLine,
3693c2c66affSColin Finck LONG* pcchSkip)
3694c2c66affSColin Finck {
3695c2c66affSColin Finck LONG i, line = cchSrc, skip = 0;
3696c2c66affSColin Finck
3697c2c66affSColin Finck FIXME("(%p)->%i %i %s %i %i %p %p\n", iface, locale, uCodePage, debugstr_an(pszSrc,cchSrc), cchSrc, cMaxColumns, pcchLine, pcchSkip);
3698c2c66affSColin Finck
3699c2c66affSColin Finck if (uCodePage == CP_USASCII && cchSrc > cMaxColumns)
3700c2c66affSColin Finck {
3701c2c66affSColin Finck for (line = cMaxColumns, i = cMaxColumns - 1; i >= 0; i--)
3702c2c66affSColin Finck {
3703c2c66affSColin Finck if (pszSrc[i] == ' ')
3704c2c66affSColin Finck {
3705c2c66affSColin Finck while (i >= 0 && pszSrc[i] == ' ')
3706c2c66affSColin Finck {
3707c2c66affSColin Finck i--;
3708c2c66affSColin Finck line--;
3709c2c66affSColin Finck skip++;
3710c2c66affSColin Finck }
3711c2c66affSColin Finck break;
3712c2c66affSColin Finck }
3713c2c66affSColin Finck }
3714c2c66affSColin Finck }
3715c2c66affSColin Finck *pcchLine = line;
3716c2c66affSColin Finck *pcchSkip = skip;
3717c2c66affSColin Finck return S_OK;
3718c2c66affSColin Finck }
3719c2c66affSColin Finck
3720c2c66affSColin Finck static const IMLangLineBreakConsoleVtbl IMLangLineBreakConsole_vtbl =
3721c2c66affSColin Finck {
3722c2c66affSColin Finck fnIMLangLineBreakConsole_QueryInterface,
3723c2c66affSColin Finck fnIMLangLineBreakConsole_AddRef,
3724c2c66affSColin Finck fnIMLangLineBreakConsole_Release,
3725c2c66affSColin Finck fnIMLangLineBreakConsole_BreakLineML,
3726c2c66affSColin Finck fnIMLangLineBreakConsole_BreakLineW,
3727c2c66affSColin Finck fnIMLangLineBreakConsole_BreakLineA
3728c2c66affSColin Finck };
3729c2c66affSColin Finck
3730c2c66affSColin Finck struct convert_charset {
3731c2c66affSColin Finck IMLangConvertCharset IMLangConvertCharset_iface;
3732c2c66affSColin Finck LONG ref;
3733c2c66affSColin Finck
3734c2c66affSColin Finck UINT src_cp;
3735c2c66affSColin Finck UINT dst_cp;
3736c2c66affSColin Finck };
3737c2c66affSColin Finck
impl_from_IMLangConvertCharset(IMLangConvertCharset * iface)3738c2c66affSColin Finck static inline struct convert_charset *impl_from_IMLangConvertCharset(IMLangConvertCharset *iface)
3739c2c66affSColin Finck {
3740c2c66affSColin Finck return CONTAINING_RECORD(iface, struct convert_charset, IMLangConvertCharset_iface);
3741c2c66affSColin Finck }
3742c2c66affSColin Finck
MLangConvertCharset_QueryInterface(IMLangConvertCharset * iface,REFIID riid,void ** obj)3743c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_QueryInterface(IMLangConvertCharset *iface, REFIID riid, void **obj)
3744c2c66affSColin Finck {
3745c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3746c2c66affSColin Finck
3747c2c66affSColin Finck TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
3748c2c66affSColin Finck
3749c2c66affSColin Finck if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMLangConvertCharset))
3750c2c66affSColin Finck {
3751c2c66affSColin Finck *obj = &This->IMLangConvertCharset_iface;
3752c2c66affSColin Finck IMLangConvertCharset_AddRef(iface);
3753c2c66affSColin Finck return S_OK;
3754c2c66affSColin Finck }
3755c2c66affSColin Finck
3756c2c66affSColin Finck *obj = NULL;
3757c2c66affSColin Finck return E_NOINTERFACE;
3758c2c66affSColin Finck }
3759c2c66affSColin Finck
MLangConvertCharset_AddRef(IMLangConvertCharset * iface)3760c2c66affSColin Finck static ULONG WINAPI MLangConvertCharset_AddRef(IMLangConvertCharset *iface)
3761c2c66affSColin Finck {
3762c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3763c2c66affSColin Finck ULONG ref = InterlockedIncrement(&This->ref);
3764c2c66affSColin Finck TRACE("(%p)->(%u)\n", This, ref);
3765c2c66affSColin Finck return ref;
3766c2c66affSColin Finck }
3767c2c66affSColin Finck
MLangConvertCharset_Release(IMLangConvertCharset * iface)3768c2c66affSColin Finck static ULONG WINAPI MLangConvertCharset_Release(IMLangConvertCharset *iface)
3769c2c66affSColin Finck {
3770c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3771c2c66affSColin Finck ULONG ref = InterlockedDecrement(&This->ref);
3772c2c66affSColin Finck
3773c2c66affSColin Finck TRACE("(%p)->(%u)\n", This, ref);
3774c2c66affSColin Finck if (!ref)
3775c2c66affSColin Finck {
3776c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, This);
3777c2c66affSColin Finck UnlockModule();
3778c2c66affSColin Finck }
3779c2c66affSColin Finck
3780c2c66affSColin Finck return ref;
3781c2c66affSColin Finck }
3782c2c66affSColin Finck
MLangConvertCharset_Initialize(IMLangConvertCharset * iface,UINT src_cp,UINT dst_cp,DWORD prop)3783c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_Initialize(IMLangConvertCharset *iface,
3784c2c66affSColin Finck UINT src_cp, UINT dst_cp, DWORD prop)
3785c2c66affSColin Finck {
3786c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3787c2c66affSColin Finck
3788c2c66affSColin Finck TRACE("(%p)->(%u %u 0x%08x)\n", This, src_cp, dst_cp, prop);
3789c2c66affSColin Finck
3790c2c66affSColin Finck prop &= ~MLCONVCHARF_USEDEFCHAR;
3791c2c66affSColin Finck if (prop)
3792c2c66affSColin Finck FIXME("property 0x%08x not supported\n", prop);
3793c2c66affSColin Finck
3794c2c66affSColin Finck This->src_cp = src_cp;
3795c2c66affSColin Finck This->dst_cp = dst_cp;
3796c2c66affSColin Finck
3797c2c66affSColin Finck return S_OK;
3798c2c66affSColin Finck }
3799c2c66affSColin Finck
MLangConvertCharset_GetSourceCodePage(IMLangConvertCharset * iface,UINT * src_cp)3800c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_GetSourceCodePage(IMLangConvertCharset *iface, UINT *src_cp)
3801c2c66affSColin Finck {
3802c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3803c2c66affSColin Finck
3804c2c66affSColin Finck TRACE("(%p)->(%p)\n", This, src_cp);
3805c2c66affSColin Finck
3806c2c66affSColin Finck if (!src_cp) return E_INVALIDARG;
3807c2c66affSColin Finck *src_cp = This->src_cp;
3808c2c66affSColin Finck return S_OK;
3809c2c66affSColin Finck }
3810c2c66affSColin Finck
MLangConvertCharset_GetDestinationCodePage(IMLangConvertCharset * iface,UINT * dst_cp)3811c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_GetDestinationCodePage(IMLangConvertCharset *iface, UINT *dst_cp)
3812c2c66affSColin Finck {
3813c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3814c2c66affSColin Finck
3815c2c66affSColin Finck TRACE("(%p)->(%p)\n", This, dst_cp);
3816c2c66affSColin Finck
3817c2c66affSColin Finck if (!dst_cp) return E_INVALIDARG;
3818c2c66affSColin Finck *dst_cp = This->dst_cp;
3819c2c66affSColin Finck return S_OK;
3820c2c66affSColin Finck }
3821c2c66affSColin Finck
MLangConvertCharset_GetProperty(IMLangConvertCharset * iface,DWORD * prop)3822c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_GetProperty(IMLangConvertCharset *iface, DWORD *prop)
3823c2c66affSColin Finck {
3824c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3825c2c66affSColin Finck FIXME("(%p)->(%p): stub\n", This, prop);
3826c2c66affSColin Finck return E_NOTIMPL;
3827c2c66affSColin Finck }
3828c2c66affSColin Finck
MLangConvertCharset_DoConversion(IMLangConvertCharset * iface,BYTE * src,UINT * src_size,BYTE * dest,UINT * dest_size)3829c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_DoConversion(IMLangConvertCharset *iface, BYTE *src,
3830c2c66affSColin Finck UINT *src_size, BYTE *dest, UINT *dest_size)
3831c2c66affSColin Finck {
3832c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3833c2c66affSColin Finck FIXME("(%p)->(%p %p %p %p): stub\n", This, src, src_size, dest, dest_size);
3834c2c66affSColin Finck return E_NOTIMPL;
3835c2c66affSColin Finck }
3836c2c66affSColin Finck
MLangConvertCharset_DoConversionToUnicode(IMLangConvertCharset * iface,CHAR * src,UINT * src_size,WCHAR * dest,UINT * dest_size)3837c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_DoConversionToUnicode(IMLangConvertCharset *iface, CHAR *src,
3838c2c66affSColin Finck UINT *src_size, WCHAR *dest, UINT *dest_size)
3839c2c66affSColin Finck {
3840c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3841c2c66affSColin Finck TRACE("(%p)->(%p %p %p %p)\n", This, src, src_size, dest, dest_size);
3842c2c66affSColin Finck return ConvertINetMultiByteToUnicode(NULL, This->src_cp, src, (INT*)src_size, dest, (INT*)dest_size);
3843c2c66affSColin Finck }
3844c2c66affSColin Finck
MLangConvertCharset_DoConversionFromUnicode(IMLangConvertCharset * iface,WCHAR * src,UINT * src_size,CHAR * dest,UINT * dest_size)3845c2c66affSColin Finck static HRESULT WINAPI MLangConvertCharset_DoConversionFromUnicode(IMLangConvertCharset *iface,
3846c2c66affSColin Finck WCHAR *src, UINT *src_size, CHAR *dest, UINT *dest_size)
3847c2c66affSColin Finck {
3848c2c66affSColin Finck struct convert_charset *This = impl_from_IMLangConvertCharset(iface);
3849c2c66affSColin Finck TRACE("(%p)->(%p %p %p %p)\n", This, src, src_size, dest, dest_size);
3850c2c66affSColin Finck return ConvertINetUnicodeToMultiByte(NULL, This->dst_cp, src, (INT*)src_size, dest, (INT*)dest_size);
3851c2c66affSColin Finck }
3852c2c66affSColin Finck
3853c2c66affSColin Finck static const IMLangConvertCharsetVtbl MLangConvertCharsetVtbl =
3854c2c66affSColin Finck {
3855c2c66affSColin Finck MLangConvertCharset_QueryInterface,
3856c2c66affSColin Finck MLangConvertCharset_AddRef,
3857c2c66affSColin Finck MLangConvertCharset_Release,
3858c2c66affSColin Finck MLangConvertCharset_Initialize,
3859c2c66affSColin Finck MLangConvertCharset_GetSourceCodePage,
3860c2c66affSColin Finck MLangConvertCharset_GetDestinationCodePage,
3861c2c66affSColin Finck MLangConvertCharset_GetProperty,
3862c2c66affSColin Finck MLangConvertCharset_DoConversion,
3863c2c66affSColin Finck MLangConvertCharset_DoConversionToUnicode,
3864c2c66affSColin Finck MLangConvertCharset_DoConversionFromUnicode
3865c2c66affSColin Finck };
3866c2c66affSColin Finck
MultiLanguage_create(IUnknown * pUnkOuter,LPVOID * ppObj)3867c2c66affSColin Finck static HRESULT MultiLanguage_create(IUnknown *pUnkOuter, LPVOID *ppObj)
3868c2c66affSColin Finck {
3869c2c66affSColin Finck MLang_impl *mlang;
3870c2c66affSColin Finck UINT i;
3871c2c66affSColin Finck
3872c2c66affSColin Finck TRACE("Creating MultiLanguage object\n");
3873c2c66affSColin Finck
3874c2c66affSColin Finck if( pUnkOuter )
3875c2c66affSColin Finck return CLASS_E_NOAGGREGATION;
3876c2c66affSColin Finck
3877c2c66affSColin Finck mlang = HeapAlloc( GetProcessHeap(), 0, sizeof (MLang_impl) );
3878c2c66affSColin Finck mlang->IMLangFontLink_iface.lpVtbl = &IMLangFontLink_vtbl;
3879c2c66affSColin Finck mlang->IMultiLanguage_iface.lpVtbl = &IMultiLanguage_vtbl;
3880c2c66affSColin Finck mlang->IMultiLanguage3_iface.lpVtbl = &IMultiLanguage3_vtbl;
3881c2c66affSColin Finck mlang->IMLangFontLink2_iface.lpVtbl = &IMLangFontLink2_vtbl;
3882c2c66affSColin Finck mlang->IMLangLineBreakConsole_iface.lpVtbl = &IMLangLineBreakConsole_vtbl;
3883c2c66affSColin Finck
3884c2c66affSColin Finck mlang->total_cp = 0;
3885ccc3eeaeSAmine Khaldi for (i = 0; i < ARRAY_SIZE(mlang_data); i++)
3886c2c66affSColin Finck mlang->total_cp += mlang_data[i].number_of_cp;
3887c2c66affSColin Finck
3888c2c66affSColin Finck /* do not enumerate unicode flavours */
3889ccc3eeaeSAmine Khaldi mlang->total_scripts = ARRAY_SIZE(mlang_data) - 1;
3890c2c66affSColin Finck
3891c2c66affSColin Finck mlang->ref = 1;
3892c2c66affSColin Finck *ppObj = &mlang->IMultiLanguage_iface;
3893c2c66affSColin Finck TRACE("returning %p\n", mlang);
3894c2c66affSColin Finck
3895c2c66affSColin Finck LockModule();
3896c2c66affSColin Finck
3897c2c66affSColin Finck return S_OK;
3898c2c66affSColin Finck }
3899c2c66affSColin Finck
MLangConvertCharset_create(IUnknown * outer,void ** obj)3900c2c66affSColin Finck static HRESULT MLangConvertCharset_create(IUnknown *outer, void **obj)
3901c2c66affSColin Finck {
3902c2c66affSColin Finck struct convert_charset *convert;
3903c2c66affSColin Finck
3904c2c66affSColin Finck if (outer)
3905c2c66affSColin Finck return CLASS_E_NOAGGREGATION;
3906c2c66affSColin Finck
3907c2c66affSColin Finck *obj = NULL;
3908c2c66affSColin Finck
3909c2c66affSColin Finck convert = HeapAlloc(GetProcessHeap(), 0, sizeof(struct convert_charset));
3910c2c66affSColin Finck if (!convert) return E_OUTOFMEMORY;
3911c2c66affSColin Finck
3912c2c66affSColin Finck convert->IMLangConvertCharset_iface.lpVtbl = &MLangConvertCharsetVtbl;
3913c2c66affSColin Finck convert->ref = 1;
3914c2c66affSColin Finck
3915c2c66affSColin Finck *obj = &convert->IMLangConvertCharset_iface;
3916c2c66affSColin Finck
3917c2c66affSColin Finck LockModule();
3918c2c66affSColin Finck
3919c2c66affSColin Finck return S_OK;
3920c2c66affSColin Finck }
3921c2c66affSColin Finck
3922c2c66affSColin Finck /******************************************************************************/
3923c2c66affSColin Finck
DllCanUnloadNow(void)3924c2c66affSColin Finck HRESULT WINAPI DllCanUnloadNow(void)
3925c2c66affSColin Finck {
3926c2c66affSColin Finck return dll_count == 0 ? S_OK : S_FALSE;
3927c2c66affSColin Finck }
3928c2c66affSColin Finck
register_codepages(void)3929ccc3eeaeSAmine Khaldi static BOOL register_codepages(void)
3930ccc3eeaeSAmine Khaldi {
3931ccc3eeaeSAmine Khaldi const struct mlang_data *family;
3932ccc3eeaeSAmine Khaldi const MIME_CP_INFO *info;
3933ccc3eeaeSAmine Khaldi HKEY db_key, key;
3934ccc3eeaeSAmine Khaldi WCHAR buf[32];
3935ccc3eeaeSAmine Khaldi LSTATUS status;
3936ccc3eeaeSAmine Khaldi
3937ccc3eeaeSAmine Khaldi static const WCHAR db_key_nameW[] = {
3938ccc3eeaeSAmine Khaldi 'M','I','M','E',
3939ccc3eeaeSAmine Khaldi '\\','D','a','t','a','b','a','s','e',
3940ccc3eeaeSAmine Khaldi '\\','C','o','d','e','p','a','g','e',0};
3941ccc3eeaeSAmine Khaldi static const WCHAR familyW[] = {'F','a','m','i','l','y',0};
3942ccc3eeaeSAmine Khaldi static const WCHAR formatW[] = {'%','u',0};
3943ccc3eeaeSAmine Khaldi
3944ccc3eeaeSAmine Khaldi status = RegCreateKeyW(HKEY_CLASSES_ROOT, db_key_nameW, &db_key);
3945ccc3eeaeSAmine Khaldi if (status != ERROR_SUCCESS)
3946ccc3eeaeSAmine Khaldi return FALSE;
3947ccc3eeaeSAmine Khaldi
3948ccc3eeaeSAmine Khaldi for (family = mlang_data; family < mlang_data + ARRAY_SIZE(mlang_data); family++)
3949ccc3eeaeSAmine Khaldi {
3950ccc3eeaeSAmine Khaldi for (info = family->mime_cp_info; info < family->mime_cp_info + family->number_of_cp; info++)
3951ccc3eeaeSAmine Khaldi {
3952853d6414SAmine Khaldi swprintf(buf, formatW, info->cp);
3953ccc3eeaeSAmine Khaldi status = RegCreateKeyW(db_key, buf, &key);
3954ccc3eeaeSAmine Khaldi if (status != ERROR_SUCCESS)
3955ccc3eeaeSAmine Khaldi continue;
3956ccc3eeaeSAmine Khaldi
3957ccc3eeaeSAmine Khaldi RegSetValueExA(key, "BodyCharset", 0, REG_SZ, (BYTE*)info->body_charset,
3958ccc3eeaeSAmine Khaldi strlen(info->body_charset) + 1);
3959ccc3eeaeSAmine Khaldi
3960ccc3eeaeSAmine Khaldi if (info->cp == family->family_codepage)
3961ccc3eeaeSAmine Khaldi {
3962ccc3eeaeSAmine Khaldi RegSetValueExA(key, "FixedWidthFont", 0, REG_SZ, (BYTE*)family->fixed_font,
3963ccc3eeaeSAmine Khaldi strlen(family->fixed_font) + 1);
3964ccc3eeaeSAmine Khaldi RegSetValueExA(key, "ProportionalFont", 0, REG_SZ, (BYTE*)family->proportional_font,
3965ccc3eeaeSAmine Khaldi strlen(family->proportional_font) + 1);
3966ccc3eeaeSAmine Khaldi }
3967ccc3eeaeSAmine Khaldi else
3968ccc3eeaeSAmine Khaldi {
3969ccc3eeaeSAmine Khaldi RegSetValueExW(key, familyW, 0, REG_DWORD, (BYTE*)&family->family_codepage,
3970ccc3eeaeSAmine Khaldi sizeof(family->family_codepage));
3971ccc3eeaeSAmine Khaldi }
3972ccc3eeaeSAmine Khaldi
3973ccc3eeaeSAmine Khaldi RegCloseKey(key);
3974ccc3eeaeSAmine Khaldi }
3975ccc3eeaeSAmine Khaldi }
3976ccc3eeaeSAmine Khaldi
3977ccc3eeaeSAmine Khaldi RegCloseKey(db_key);
3978ccc3eeaeSAmine Khaldi return TRUE;
3979ccc3eeaeSAmine Khaldi }
3980c2c66affSColin Finck
3981c2c66affSColin Finck /***********************************************************************
3982c2c66affSColin Finck * DllRegisterServer (MLANG.@)
3983c2c66affSColin Finck */
DllRegisterServer(void)3984c2c66affSColin Finck HRESULT WINAPI DllRegisterServer(void)
3985c2c66affSColin Finck {
3986ccc3eeaeSAmine Khaldi if(!register_codepages())
3987ccc3eeaeSAmine Khaldi return E_FAIL;
3988c2c66affSColin Finck return __wine_register_resources( instance );
3989c2c66affSColin Finck }
3990c2c66affSColin Finck
3991c2c66affSColin Finck /***********************************************************************
3992c2c66affSColin Finck * DllUnregisterServer (MLANG.@)
3993c2c66affSColin Finck */
DllUnregisterServer(void)3994c2c66affSColin Finck HRESULT WINAPI DllUnregisterServer(void)
3995c2c66affSColin Finck {
3996c2c66affSColin Finck return __wine_unregister_resources( instance );
3997c2c66affSColin Finck }
3998c2c66affSColin Finck
GetGlobalFontLinkObject(void ** unknown)3999c2c66affSColin Finck HRESULT WINAPI GetGlobalFontLinkObject(void **unknown)
4000c2c66affSColin Finck {
4001c2c66affSColin Finck if (!unknown) return E_INVALIDARG;
4002c2c66affSColin Finck
4003c2c66affSColin Finck FIXME("%p: stub\n", unknown);
4004c2c66affSColin Finck
4005c2c66affSColin Finck return S_FALSE;
4006c2c66affSColin Finck }
4007