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