771
|
1 /* Win32 internationalization functions.
|
2367
|
2 Copyright (C) 2000, 2001, 2002, 2004 Ben Wing.
|
771
|
3 Copyright (C) 2000 IKEYAMA Tomonori.
|
|
4
|
|
5 This file is part of XEmacs.
|
|
6
|
|
7 XEmacs is free software; you can redistribute it and/or modify it
|
|
8 under the terms of the GNU General Public License as published by the
|
|
9 Free Software Foundation; either version 2, or (at your option) any
|
|
10 later version.
|
|
11
|
|
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
15 for more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with XEmacs; see the file COPYING. If not, write to
|
|
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
20 Boston, MA 02111-1307, USA. */
|
|
21
|
|
22 /* Synched up with: Not in FSF. */
|
|
23
|
|
24 /* Authorship:
|
|
25
|
|
26 Current primary author: Ben Wing <ben@xemacs.org>
|
|
27
|
|
28 Created summer 2000 by Ben Wing. Almost completely written by Ben Wing.
|
|
29 Little bits of code in some of the Lisp primitives from FSF Emacs.
|
|
30 Versions of wcscpy, wcsncpy from Cygwin newlib.
|
|
31
|
|
32 Coding systems written by Ben Wing in file-coding.c; moved here Sep 2001.
|
|
33 */
|
|
34
|
|
35 #include <config.h>
|
|
36 #include "lisp.h"
|
|
37
|
|
38 #include "elhash.h"
|
|
39 #include "faces.h"
|
|
40 #include "file-coding.h"
|
872
|
41 #include "frame-impl.h"
|
|
42 #include "window-impl.h"
|
771
|
43
|
872
|
44 #include "console-msw-impl.h"
|
|
45 #include "objects-msw-impl.h"
|
771
|
46
|
|
47 #ifndef CYGWIN_HEADERS
|
|
48 # include <mbctype.h>
|
|
49 #elif defined (MINGW)
|
|
50 int _setmbcp (int);
|
|
51 int _getmbcp (void);
|
|
52 #else
|
|
53 # define NO_EXT_MULTIBYTE_FEATURES
|
|
54 #endif
|
|
55
|
2367
|
56
|
|
57
|
|
58 /*
|
|
59
|
|
60 Detailed info on Microsoft Windows-Related Multilingual Issues:
|
|
61
|
|
62 (Info-goto-node "(internals)Microsoft Windows-Related Multilingual Issues")
|
|
63 */
|
|
64
|
771
|
65 Lisp_Object Qmswindows_multibyte, Qmswindows_multibyte_to_unicode;
|
|
66 Lisp_Object Qmswindows_tstr, Qmswindows_unicode;
|
|
67 Lisp_Object Qmswindows_multibyte_system_default;
|
|
68
|
|
69 Lisp_Object Qansi, Qoem, Qmac, Qebcdic;
|
|
70 /* Qcode_page, Qlocale, Qcurrent, Quser_default, Qsystem_default in
|
|
71 general-slots.h */
|
|
72
|
|
73 #ifdef MULE
|
|
74
|
|
75 static Lisp_Object Vmswindows_charset_code_page_table;
|
872
|
76 static Lisp_Object Vmswindows_charset_registry_table;
|
771
|
77
|
|
78 LCID current_locale;
|
|
79
|
|
80
|
|
81 /************************************************************************/
|
|
82 /* Language/locale/code page conversion functions */
|
|
83 /************************************************************************/
|
|
84
|
|
85 struct lang_to_string
|
|
86 {
|
|
87 int code;
|
|
88 char *string;
|
|
89 };
|
|
90
|
|
91 struct lang_to_string lang_to_string_table[] =
|
|
92 {
|
|
93 /* These names change from version to version of VC++, so it's easiest
|
|
94 just to bracket them all with ifdefs. */
|
|
95 #ifdef LANG_AFRIKAANS
|
|
96 { LANG_AFRIKAANS, "AFRIKAANS" },
|
|
97 #endif
|
|
98 #ifdef LANG_ALBANIAN
|
|
99 { LANG_ALBANIAN, "ALBANIAN" },
|
|
100 #endif
|
|
101 #ifdef LANG_ARABIC
|
|
102 { LANG_ARABIC, "ARABIC" },
|
|
103 #endif
|
|
104 #ifdef LANG_ARMENIAN
|
|
105 { LANG_ARMENIAN, "ARMENIAN" },
|
|
106 #endif
|
|
107 #ifdef LANG_ASSAMESE
|
|
108 { LANG_ASSAMESE, "ASSAMESE" },
|
|
109 #endif
|
|
110 #ifdef LANG_AZERI
|
|
111 { LANG_AZERI, "AZERI" },
|
|
112 #endif
|
|
113 #ifdef LANG_BASQUE
|
|
114 { LANG_BASQUE, "BASQUE" },
|
|
115 #endif
|
|
116 #ifdef LANG_BELARUSIAN
|
|
117 { LANG_BELARUSIAN, "BELARUSIAN" },
|
|
118 #endif
|
|
119 #ifdef LANG_BENGALI
|
|
120 { LANG_BENGALI, "BENGALI" },
|
|
121 #endif
|
|
122 #ifdef LANG_BULGARIAN
|
|
123 { LANG_BULGARIAN, "BULGARIAN" },
|
|
124 #endif
|
|
125 #ifdef LANG_CATALAN
|
|
126 { LANG_CATALAN, "CATALAN" },
|
|
127 #endif
|
|
128 #ifdef LANG_CHINESE
|
|
129 { LANG_CHINESE, "CHINESE" },
|
|
130 #endif
|
|
131 #ifdef LANG_CROATIAN
|
|
132 { LANG_CROATIAN, "CROATIAN" },
|
|
133 #endif
|
|
134 #ifdef LANG_CZECH
|
|
135 { LANG_CZECH, "CZECH" },
|
|
136 #endif
|
|
137 #ifdef LANG_DANISH
|
|
138 { LANG_DANISH, "DANISH" },
|
|
139 #endif
|
|
140 #ifdef LANG_DUTCH
|
|
141 { LANG_DUTCH, "DUTCH" },
|
|
142 #endif
|
|
143 #ifdef LANG_ENGLISH
|
|
144 { LANG_ENGLISH, "ENGLISH" },
|
|
145 #endif
|
|
146 #ifdef LANG_ESTONIAN
|
|
147 { LANG_ESTONIAN, "ESTONIAN" },
|
|
148 #endif
|
|
149 #ifdef LANG_FAEROESE
|
|
150 { LANG_FAEROESE, "FAEROESE" },
|
|
151 #endif
|
|
152 #ifdef LANG_FARSI
|
|
153 { LANG_FARSI, "FARSI" },
|
|
154 #endif
|
|
155 #ifdef LANG_FINNISH
|
|
156 { LANG_FINNISH, "FINNISH" },
|
|
157 #endif
|
|
158 #ifdef LANG_FRENCH
|
|
159 { LANG_FRENCH, "FRENCH" },
|
|
160 #endif
|
|
161 #ifdef LANG_GEORGIAN
|
|
162 { LANG_GEORGIAN, "GEORGIAN" },
|
|
163 #endif
|
|
164 #ifdef LANG_GERMAN
|
|
165 { LANG_GERMAN, "GERMAN" },
|
|
166 #endif
|
|
167 #ifdef LANG_GREEK
|
|
168 { LANG_GREEK, "GREEK" },
|
|
169 #endif
|
|
170 #ifdef LANG_GUJARATI
|
|
171 { LANG_GUJARATI, "GUJARATI" },
|
|
172 #endif
|
|
173 #ifdef LANG_HEBREW
|
|
174 { LANG_HEBREW, "HEBREW" },
|
|
175 #endif
|
|
176 #ifdef LANG_HINDI
|
|
177 { LANG_HINDI, "HINDI" },
|
|
178 #endif
|
|
179 #ifdef LANG_HUNGARIAN
|
|
180 { LANG_HUNGARIAN, "HUNGARIAN" },
|
|
181 #endif
|
|
182 #ifdef LANG_ICELANDIC
|
|
183 { LANG_ICELANDIC, "ICELANDIC" },
|
|
184 #endif
|
|
185 #ifdef LANG_INDONESIAN
|
|
186 { LANG_INDONESIAN, "INDONESIAN" },
|
|
187 #endif
|
|
188 #ifdef LANG_ITALIAN
|
|
189 { LANG_ITALIAN, "ITALIAN" },
|
|
190 #endif
|
|
191 #ifdef LANG_JAPANESE
|
|
192 { LANG_JAPANESE, "JAPANESE" },
|
|
193 #endif
|
|
194 #ifdef LANG_KANNADA
|
|
195 { LANG_KANNADA, "KANNADA" },
|
|
196 #endif
|
|
197 #ifdef LANG_KASHMIRI
|
|
198 { LANG_KASHMIRI, "KASHMIRI" },
|
|
199 #endif
|
|
200 #ifdef LANG_KAZAK
|
|
201 { LANG_KAZAK, "KAZAK" },
|
|
202 #endif
|
|
203 #ifdef LANG_KONKANI
|
|
204 { LANG_KONKANI, "KONKANI" },
|
|
205 #endif
|
|
206 #ifdef LANG_KOREAN
|
|
207 { LANG_KOREAN, "KOREAN" },
|
|
208 #endif
|
|
209 #ifdef LANG_LATVIAN
|
|
210 { LANG_LATVIAN, "LATVIAN" },
|
|
211 #endif
|
|
212 #ifdef LANG_LITHUANIAN
|
|
213 { LANG_LITHUANIAN, "LITHUANIAN" },
|
|
214 #endif
|
|
215 #ifdef LANG_MACEDONIAN
|
|
216 { LANG_MACEDONIAN, "MACEDONIAN" },
|
|
217 #endif
|
|
218 #ifdef LANG_MALAY
|
|
219 { LANG_MALAY, "MALAY" },
|
|
220 #endif
|
|
221 #ifdef LANG_MALAYALAM
|
|
222 { LANG_MALAYALAM, "MALAYALAM" },
|
|
223 #endif
|
|
224 #ifdef LANG_MANIPURI
|
|
225 { LANG_MANIPURI, "MANIPURI" },
|
|
226 #endif
|
|
227 #ifdef LANG_MARATHI
|
|
228 { LANG_MARATHI, "MARATHI" },
|
|
229 #endif
|
|
230 #ifdef LANG_NEPALI
|
|
231 { LANG_NEPALI, "NEPALI" },
|
|
232 #endif
|
|
233 #ifdef LANG_NEUTRAL
|
|
234 { LANG_NEUTRAL, "NEUTRAL" },
|
|
235 #endif
|
|
236 #ifdef LANG_NORWEGIAN
|
|
237 { LANG_NORWEGIAN, "NORWEGIAN" },
|
|
238 #endif
|
|
239 #ifdef LANG_ORIYA
|
|
240 { LANG_ORIYA, "ORIYA" },
|
|
241 #endif
|
|
242 #ifdef LANG_POLISH
|
|
243 { LANG_POLISH, "POLISH" },
|
|
244 #endif
|
|
245 #ifdef LANG_PORTUGUESE
|
|
246 { LANG_PORTUGUESE, "PORTUGUESE" },
|
|
247 #endif
|
|
248 #ifdef LANG_PUNJABI
|
|
249 { LANG_PUNJABI, "PUNJABI" },
|
|
250 #endif
|
|
251 #ifdef LANG_ROMANIAN
|
|
252 { LANG_ROMANIAN, "ROMANIAN" },
|
|
253 #endif
|
|
254 #ifdef LANG_RUSSIAN
|
|
255 { LANG_RUSSIAN, "RUSSIAN" },
|
|
256 #endif
|
|
257 #ifdef LANG_SANSKRIT
|
|
258 { LANG_SANSKRIT, "SANSKRIT" },
|
|
259 #endif
|
|
260 #ifdef LANG_SERBIAN
|
|
261 { LANG_SERBIAN, "SERBIAN" },
|
|
262 #endif
|
|
263 #ifdef LANG_SINDHI
|
|
264 { LANG_SINDHI, "SINDHI" },
|
|
265 #endif
|
|
266 #ifdef LANG_SLOVAK
|
|
267 { LANG_SLOVAK, "SLOVAK" },
|
|
268 #endif
|
|
269 #ifdef LANG_SLOVENIAN
|
|
270 { LANG_SLOVENIAN, "SLOVENIAN" },
|
|
271 #endif
|
|
272 #ifdef LANG_SPANISH
|
|
273 { LANG_SPANISH, "SPANISH" },
|
|
274 #endif
|
|
275 #ifdef LANG_SWAHILI
|
|
276 { LANG_SWAHILI, "SWAHILI" },
|
|
277 #endif
|
|
278 #ifdef LANG_SWEDISH
|
|
279 { LANG_SWEDISH, "SWEDISH" },
|
|
280 #endif
|
|
281 #ifdef LANG_TAMIL
|
|
282 { LANG_TAMIL, "TAMIL" },
|
|
283 #endif
|
|
284 #ifdef LANG_TATAR
|
|
285 { LANG_TATAR, "TATAR" },
|
|
286 #endif
|
|
287 #ifdef LANG_TELUGU
|
|
288 { LANG_TELUGU, "TELUGU" },
|
|
289 #endif
|
|
290 #ifdef LANG_THAI
|
|
291 { LANG_THAI, "THAI" },
|
|
292 #endif
|
|
293 #ifdef LANG_TURKISH
|
|
294 { LANG_TURKISH, "TURKISH" },
|
|
295 #endif
|
|
296 #ifdef LANG_UKRAINIAN
|
|
297 { LANG_UKRAINIAN, "UKRAINIAN" },
|
|
298 #endif
|
|
299 #ifdef LANG_URDU
|
|
300 { LANG_URDU, "URDU" },
|
|
301 #endif
|
|
302 #ifdef LANG_UZBEK
|
|
303 { LANG_UZBEK, "UZBEK" },
|
|
304 #endif
|
|
305 #ifdef LANG_VIETNAMESE
|
|
306 { LANG_VIETNAMESE, "VIETNAMESE" },
|
|
307 #endif
|
|
308 };
|
|
309
|
|
310 struct lang_to_string sublang_to_string_table[] =
|
|
311 {
|
|
312 { LANG_ARABIC, 0 },
|
|
313 #ifdef SUBLANG_ARABIC_ALGERIA
|
|
314 { SUBLANG_ARABIC_ALGERIA, "ARABIC_ALGERIA" },
|
|
315 #endif
|
|
316 #ifdef SUBLANG_ARABIC_BAHRAIN
|
|
317 { SUBLANG_ARABIC_BAHRAIN, "ARABIC_BAHRAIN" },
|
|
318 #endif
|
|
319 #ifdef SUBLANG_ARABIC_EGYPT
|
|
320 { SUBLANG_ARABIC_EGYPT, "ARABIC_EGYPT" },
|
|
321 #endif
|
|
322 #ifdef SUBLANG_ARABIC_IRAQ
|
|
323 { SUBLANG_ARABIC_IRAQ, "ARABIC_IRAQ" },
|
|
324 #endif
|
|
325 #ifdef SUBLANG_ARABIC_JORDAN
|
|
326 { SUBLANG_ARABIC_JORDAN, "ARABIC_JORDAN" },
|
|
327 #endif
|
|
328 #ifdef SUBLANG_ARABIC_KUWAIT
|
|
329 { SUBLANG_ARABIC_KUWAIT, "ARABIC_KUWAIT" },
|
|
330 #endif
|
|
331 #ifdef SUBLANG_ARABIC_LEBANON
|
|
332 { SUBLANG_ARABIC_LEBANON, "ARABIC_LEBANON" },
|
|
333 #endif
|
|
334 #ifdef SUBLANG_ARABIC_LIBYA
|
|
335 { SUBLANG_ARABIC_LIBYA, "ARABIC_LIBYA" },
|
|
336 #endif
|
|
337 #ifdef SUBLANG_ARABIC_MOROCCO
|
|
338 { SUBLANG_ARABIC_MOROCCO, "ARABIC_MOROCCO" },
|
|
339 #endif
|
|
340 #ifdef SUBLANG_ARABIC_OMAN
|
|
341 { SUBLANG_ARABIC_OMAN, "ARABIC_OMAN" },
|
|
342 #endif
|
|
343 #ifdef SUBLANG_ARABIC_QATAR
|
|
344 { SUBLANG_ARABIC_QATAR, "ARABIC_QATAR" },
|
|
345 #endif
|
|
346 #ifdef SUBLANG_ARABIC_SAUDI_ARABIA
|
|
347 { SUBLANG_ARABIC_SAUDI_ARABIA, "ARABIC_SAUDI_ARABIA" },
|
|
348 #endif
|
|
349 #ifdef SUBLANG_ARABIC_SYRIA
|
|
350 { SUBLANG_ARABIC_SYRIA, "ARABIC_SYRIA" },
|
|
351 #endif
|
|
352 #ifdef SUBLANG_ARABIC_TUNISIA
|
|
353 { SUBLANG_ARABIC_TUNISIA, "ARABIC_TUNISIA" },
|
|
354 #endif
|
|
355 #ifdef SUBLANG_ARABIC_UAE
|
|
356 { SUBLANG_ARABIC_UAE, "ARABIC_UAE" },
|
|
357 #endif
|
|
358 #ifdef SUBLANG_ARABIC_YEMEN
|
|
359 { SUBLANG_ARABIC_YEMEN, "ARABIC_YEMEN" },
|
|
360 #endif
|
|
361 { LANG_AZERI, 0 },
|
|
362 #ifdef SUBLANG_AZERI_CYRILLIC
|
|
363 { SUBLANG_AZERI_CYRILLIC, "AZERI_CYRILLIC" },
|
|
364 #endif
|
|
365 #ifdef SUBLANG_AZERI_LATIN
|
|
366 { SUBLANG_AZERI_LATIN, "AZERI_LATIN" },
|
|
367 #endif
|
|
368 { LANG_CHINESE, 0 },
|
|
369 #ifdef SUBLANG_CHINESE_HONGKONG
|
|
370 { SUBLANG_CHINESE_HONGKONG, "CHINESE_HONGKONG" },
|
|
371 #endif
|
|
372 #ifdef SUBLANG_CHINESE_MACAU
|
|
373 { SUBLANG_CHINESE_MACAU, "CHINESE_MACAU" },
|
|
374 #endif
|
|
375 #ifdef SUBLANG_CHINESE_SIMPLIFIED
|
|
376 { SUBLANG_CHINESE_SIMPLIFIED, "CHINESE_SIMPLIFIED" },
|
|
377 #endif
|
|
378 #ifdef SUBLANG_CHINESE_SINGAPORE
|
|
379 { SUBLANG_CHINESE_SINGAPORE, "CHINESE_SINGAPORE" },
|
|
380 #endif
|
|
381 #ifdef SUBLANG_CHINESE_TRADITIONAL
|
|
382 { SUBLANG_CHINESE_TRADITIONAL, "CHINESE_TRADITIONAL" },
|
|
383 #endif
|
|
384 { LANG_DUTCH, 0 },
|
|
385 #ifdef SUBLANG_DUTCH
|
|
386 { SUBLANG_DUTCH, "DUTCH" },
|
|
387 #endif
|
|
388 #ifdef SUBLANG_DUTCH_BELGIAN
|
|
389 { SUBLANG_DUTCH_BELGIAN, "DUTCH_BELGIAN" },
|
|
390 #endif
|
|
391 { LANG_ENGLISH, 0 },
|
|
392 #ifdef SUBLANG_ENGLISH_AUS
|
|
393 { SUBLANG_ENGLISH_AUS, "ENGLISH_AUS" },
|
|
394 #endif
|
|
395 #ifdef SUBLANG_ENGLISH_BELIZE
|
|
396 { SUBLANG_ENGLISH_BELIZE, "ENGLISH_BELIZE" },
|
|
397 #endif
|
|
398 #ifdef SUBLANG_ENGLISH_CAN
|
|
399 { SUBLANG_ENGLISH_CAN, "ENGLISH_CAN" },
|
|
400 #endif
|
|
401 #ifdef SUBLANG_ENGLISH_CARIBBEAN
|
|
402 { SUBLANG_ENGLISH_CARIBBEAN, "ENGLISH_CARIBBEAN" },
|
|
403 #endif
|
|
404 #ifdef SUBLANG_ENGLISH_EIRE
|
|
405 { SUBLANG_ENGLISH_EIRE, "ENGLISH_EIRE" },
|
|
406 #endif
|
|
407 #ifdef SUBLANG_ENGLISH_JAMAICA
|
|
408 { SUBLANG_ENGLISH_JAMAICA, "ENGLISH_JAMAICA" },
|
|
409 #endif
|
|
410 #ifdef SUBLANG_ENGLISH_NZ
|
|
411 { SUBLANG_ENGLISH_NZ, "ENGLISH_NZ" },
|
|
412 #endif
|
|
413 #ifdef SUBLANG_ENGLISH_PHILIPPINES
|
|
414 { SUBLANG_ENGLISH_PHILIPPINES, "ENGLISH_PHILIPPINES" },
|
|
415 #endif
|
|
416 #ifdef SUBLANG_ENGLISH_SOUTH_AFRICA
|
|
417 { SUBLANG_ENGLISH_SOUTH_AFRICA, "ENGLISH_SOUTH_AFRICA" },
|
|
418 #endif
|
|
419 #ifdef SUBLANG_ENGLISH_TRINIDAD
|
|
420 { SUBLANG_ENGLISH_TRINIDAD, "ENGLISH_TRINIDAD" },
|
|
421 #endif
|
|
422 #ifdef SUBLANG_ENGLISH_UK
|
|
423 { SUBLANG_ENGLISH_UK, "ENGLISH_UK" },
|
|
424 #endif
|
|
425 #ifdef SUBLANG_ENGLISH_US
|
|
426 { SUBLANG_ENGLISH_US, "ENGLISH_US" },
|
|
427 #endif
|
|
428 #ifdef SUBLANG_ENGLISH_ZIMBABWE
|
|
429 { SUBLANG_ENGLISH_ZIMBABWE, "ENGLISH_ZIMBABWE" },
|
|
430 #endif
|
|
431 { LANG_FRENCH, 0 },
|
|
432 #ifdef SUBLANG_FRENCH
|
|
433 { SUBLANG_FRENCH, "FRENCH" },
|
|
434 #endif
|
|
435 #ifdef SUBLANG_FRENCH_BELGIAN
|
|
436 { SUBLANG_FRENCH_BELGIAN, "FRENCH_BELGIAN" },
|
|
437 #endif
|
|
438 #ifdef SUBLANG_FRENCH_CANADIAN
|
|
439 { SUBLANG_FRENCH_CANADIAN, "FRENCH_CANADIAN" },
|
|
440 #endif
|
|
441 #ifdef SUBLANG_FRENCH_LUXEMBOURG
|
|
442 { SUBLANG_FRENCH_LUXEMBOURG, "FRENCH_LUXEMBOURG" },
|
|
443 #endif
|
|
444 #ifdef SUBLANG_FRENCH_MONACO
|
|
445 { SUBLANG_FRENCH_MONACO, "FRENCH_MONACO" },
|
|
446 #endif
|
|
447 #ifdef SUBLANG_FRENCH_SWISS
|
|
448 { SUBLANG_FRENCH_SWISS, "FRENCH_SWISS" },
|
|
449 #endif
|
|
450 { LANG_GERMAN, 0 },
|
|
451 #ifdef SUBLANG_GERMAN
|
|
452 { SUBLANG_GERMAN, "GERMAN" },
|
|
453 #endif
|
|
454 #ifdef SUBLANG_GERMAN_AUSTRIAN
|
|
455 { SUBLANG_GERMAN_AUSTRIAN, "GERMAN_AUSTRIAN" },
|
|
456 #endif
|
|
457 #ifdef SUBLANG_GERMAN_LIECHTENSTEIN
|
|
458 { SUBLANG_GERMAN_LIECHTENSTEIN, "GERMAN_LIECHTENSTEIN" },
|
|
459 #endif
|
|
460 #ifdef SUBLANG_GERMAN_LUXEMBOURG
|
|
461 { SUBLANG_GERMAN_LUXEMBOURG, "GERMAN_LUXEMBOURG" },
|
|
462 #endif
|
|
463 #ifdef SUBLANG_GERMAN_SWISS
|
|
464 { SUBLANG_GERMAN_SWISS, "GERMAN_SWISS" },
|
|
465 #endif
|
|
466 { LANG_ITALIAN, 0 },
|
|
467 #ifdef SUBLANG_ITALIAN
|
|
468 { SUBLANG_ITALIAN, "ITALIAN" },
|
|
469 #endif
|
|
470 #ifdef SUBLANG_ITALIAN_SWISS
|
|
471 { SUBLANG_ITALIAN_SWISS, "ITALIAN_SWISS" },
|
|
472 #endif
|
|
473 { LANG_KASHMIRI, 0 },
|
|
474 #ifdef SUBLANG_KASHMIRI_INDIA
|
|
475 { SUBLANG_KASHMIRI_INDIA, "KASHMIRI_INDIA" },
|
|
476 #endif
|
|
477 { LANG_KOREAN, 0 },
|
|
478 #ifdef SUBLANG_KOREAN
|
|
479 { SUBLANG_KOREAN, "KOREAN" },
|
|
480 #endif
|
|
481 #ifdef SUBLANG_KOREAN_JOHAB
|
|
482 /* NOTE: Omitted in more recent versions of VC++ (e.g. v6.0) */
|
|
483 { SUBLANG_KOREAN_JOHAB, "KOREAN_JOHAB" },
|
|
484 #endif
|
|
485 { LANG_LITHUANIAN, 0 },
|
|
486 #ifdef SUBLANG_LITHUANIAN
|
|
487 { SUBLANG_LITHUANIAN, "LITHUANIAN" },
|
|
488 #endif
|
|
489 #ifdef SUBLANG_LITHUANIAN_CLASSIC
|
|
490 { SUBLANG_LITHUANIAN_CLASSIC, "LITHUANIAN_CLASSIC" },
|
|
491 #endif
|
|
492 { LANG_MALAY, 0 },
|
|
493 #ifdef SUBLANG_MALAY_BRUNEI_DARUSSALAM
|
|
494 { SUBLANG_MALAY_BRUNEI_DARUSSALAM, "MALAY_BRUNEI_DARUSSALAM" },
|
|
495 #endif
|
|
496 #ifdef SUBLANG_MALAY_MALAYSIA
|
|
497 { SUBLANG_MALAY_MALAYSIA, "MALAY_MALAYSIA" },
|
|
498 #endif
|
|
499 { LANG_NEPALI, 0 },
|
|
500 #ifdef SUBLANG_NEPALI_INDIA
|
|
501 { SUBLANG_NEPALI_INDIA, "NEPALI_INDIA" },
|
|
502 #endif
|
|
503 { LANG_NEUTRAL, 0 },
|
|
504 #ifdef SUBLANG_NEUTRAL
|
|
505 { SUBLANG_NEUTRAL, "NEUTRAL" },
|
|
506 #endif
|
|
507 { LANG_NORWEGIAN, 0 },
|
|
508 #ifdef SUBLANG_NORWEGIAN_BOKMAL
|
|
509 { SUBLANG_NORWEGIAN_BOKMAL, "NORWEGIAN_BOKMAL" },
|
|
510 #endif
|
|
511 #ifdef SUBLANG_NORWEGIAN_NYNORSK
|
|
512 { SUBLANG_NORWEGIAN_NYNORSK, "NORWEGIAN_NYNORSK" },
|
|
513 #endif
|
|
514 { LANG_PORTUGUESE, 0 },
|
|
515 #ifdef SUBLANG_PORTUGUESE
|
|
516 { SUBLANG_PORTUGUESE, "PORTUGUESE" },
|
|
517 #endif
|
|
518 #ifdef SUBLANG_PORTUGUESE_BRAZILIAN
|
|
519 { SUBLANG_PORTUGUESE_BRAZILIAN, "PORTUGUESE_BRAZILIAN" },
|
|
520 #endif
|
|
521 { LANG_SERBIAN, 0 },
|
|
522 #ifdef SUBLANG_SERBIAN_CYRILLIC
|
|
523 { SUBLANG_SERBIAN_CYRILLIC, "SERBIAN_CYRILLIC" },
|
|
524 #endif
|
|
525 #ifdef SUBLANG_SERBIAN_LATIN
|
|
526 { SUBLANG_SERBIAN_LATIN, "SERBIAN_LATIN" },
|
|
527 #endif
|
|
528 { LANG_SPANISH, 0 },
|
|
529 #ifdef SUBLANG_SPANISH
|
|
530 { SUBLANG_SPANISH, "SPANISH" },
|
|
531 #endif
|
|
532 #ifdef SUBLANG_SPANISH_ARGENTINA
|
|
533 { SUBLANG_SPANISH_ARGENTINA, "SPANISH_ARGENTINA" },
|
|
534 #endif
|
|
535 #ifdef SUBLANG_SPANISH_BOLIVIA
|
|
536 { SUBLANG_SPANISH_BOLIVIA, "SPANISH_BOLIVIA" },
|
|
537 #endif
|
|
538 #ifdef SUBLANG_SPANISH_CHILE
|
|
539 { SUBLANG_SPANISH_CHILE, "SPANISH_CHILE" },
|
|
540 #endif
|
|
541 #ifdef SUBLANG_SPANISH_COLOMBIA
|
|
542 { SUBLANG_SPANISH_COLOMBIA, "SPANISH_COLOMBIA" },
|
|
543 #endif
|
|
544 #ifdef SUBLANG_SPANISH_COSTA_RICA
|
|
545 { SUBLANG_SPANISH_COSTA_RICA, "SPANISH_COSTA_RICA" },
|
|
546 #endif
|
|
547 #ifdef SUBLANG_SPANISH_DOMINICAN_REPUBLIC
|
|
548 { SUBLANG_SPANISH_DOMINICAN_REPUBLIC, "SPANISH_DOMINICAN_REPUBLIC" },
|
|
549 #endif
|
|
550 #ifdef SUBLANG_SPANISH_ECUADOR
|
|
551 { SUBLANG_SPANISH_ECUADOR, "SPANISH_ECUADOR" },
|
|
552 #endif
|
|
553 #ifdef SUBLANG_SPANISH_EL_SALVADOR
|
|
554 { SUBLANG_SPANISH_EL_SALVADOR, "SPANISH_EL_SALVADOR" },
|
|
555 #endif
|
|
556 #ifdef SUBLANG_SPANISH_GUATEMALA
|
|
557 { SUBLANG_SPANISH_GUATEMALA, "SPANISH_GUATEMALA" },
|
|
558 #endif
|
|
559 #ifdef SUBLANG_SPANISH_HONDURAS
|
|
560 { SUBLANG_SPANISH_HONDURAS, "SPANISH_HONDURAS" },
|
|
561 #endif
|
|
562 #ifdef SUBLANG_SPANISH_MEXICAN
|
|
563 { SUBLANG_SPANISH_MEXICAN, "SPANISH_MEXICAN" },
|
|
564 #endif
|
|
565 #ifdef SUBLANG_SPANISH_MODERN
|
|
566 { SUBLANG_SPANISH_MODERN, "SPANISH_MODERN" },
|
|
567 #endif
|
|
568 #ifdef SUBLANG_SPANISH_NICARAGUA
|
|
569 { SUBLANG_SPANISH_NICARAGUA, "SPANISH_NICARAGUA" },
|
|
570 #endif
|
|
571 #ifdef SUBLANG_SPANISH_PANAMA
|
|
572 { SUBLANG_SPANISH_PANAMA, "SPANISH_PANAMA" },
|
|
573 #endif
|
|
574 #ifdef SUBLANG_SPANISH_PARAGUAY
|
|
575 { SUBLANG_SPANISH_PARAGUAY, "SPANISH_PARAGUAY" },
|
|
576 #endif
|
|
577 #ifdef SUBLANG_SPANISH_PERU
|
|
578 { SUBLANG_SPANISH_PERU, "SPANISH_PERU" },
|
|
579 #endif
|
|
580 #ifdef SUBLANG_SPANISH_PUERTO_RICO
|
|
581 { SUBLANG_SPANISH_PUERTO_RICO, "SPANISH_PUERTO_RICO" },
|
|
582 #endif
|
|
583 #ifdef SUBLANG_SPANISH_URUGUAY
|
|
584 { SUBLANG_SPANISH_URUGUAY, "SPANISH_URUGUAY" },
|
|
585 #endif
|
|
586 #ifdef SUBLANG_SPANISH_VENEZUELA
|
|
587 { SUBLANG_SPANISH_VENEZUELA, "SPANISH_VENEZUELA" },
|
|
588 #endif
|
|
589 { LANG_SWEDISH, 0 },
|
|
590 #ifdef SUBLANG_SWEDISH
|
|
591 { SUBLANG_SWEDISH, "SWEDISH" },
|
|
592 #endif
|
|
593 #ifdef SUBLANG_SWEDISH_FINLAND
|
|
594 { SUBLANG_SWEDISH_FINLAND, "SWEDISH_FINLAND" },
|
|
595 #endif
|
|
596 { LANG_URDU, 0 },
|
|
597 #ifdef SUBLANG_URDU_INDIA
|
|
598 { SUBLANG_URDU_INDIA, "URDU_INDIA" },
|
|
599 #endif
|
|
600 #ifdef SUBLANG_URDU_PAKISTAN
|
|
601 { SUBLANG_URDU_PAKISTAN, "URDU_PAKISTAN" },
|
|
602 #endif
|
|
603 { LANG_UZBEK, 0 },
|
|
604 #ifdef SUBLANG_UZBEK_CYRILLIC
|
|
605 { SUBLANG_UZBEK_CYRILLIC, "UZBEK_CYRILLIC" },
|
|
606 #endif
|
|
607 #ifdef SUBLANG_UZBEK_LATIN
|
|
608 { SUBLANG_UZBEK_LATIN, "UZBEK_LATIN" },
|
|
609 #endif
|
|
610 };
|
|
611
|
|
612 static int
|
|
613 lang_to_langcode (Lisp_Object lang, struct lang_to_string *table,
|
|
614 int table_size)
|
|
615 {
|
|
616 int i;
|
|
617
|
|
618 for (i = 0; i < table_size; i++)
|
2367
|
619 if (!qxestrcmp_ascii (XSTRING_DATA (lang), table[i].string))
|
771
|
620 return table[i].code;
|
|
621 return -1;
|
|
622 }
|
|
623
|
|
624 static int
|
|
625 sublang_to_langcode (Lisp_Object lang, struct lang_to_string *table,
|
|
626 int table_size)
|
|
627 {
|
|
628 int i;
|
|
629
|
|
630 for (i = 0; i < table_size; i++)
|
|
631 if (table[i].string &&
|
2367
|
632 !qxestrcmp_ascii (XSTRING_DATA (lang), table[i].string))
|
771
|
633 return table[i].code;
|
|
634
|
2367
|
635 if (!qxestrcmp_ascii (XSTRING_DATA (lang), "NEUTRAL"))
|
771
|
636 return SUBLANG_NEUTRAL;
|
2367
|
637 if (!qxestrcmp_ascii (XSTRING_DATA (lang), "DEFAULT"))
|
771
|
638 return SUBLANG_DEFAULT;
|
2367
|
639 if (!qxestrcmp_ascii (XSTRING_DATA (lang), "SYS_DEFAULT"))
|
771
|
640 return SUBLANG_SYS_DEFAULT;
|
|
641
|
|
642 return -1;
|
|
643 }
|
|
644
|
|
645 static Lisp_Object
|
|
646 langcode_to_lang (int code, struct lang_to_string *table,
|
|
647 int table_size)
|
|
648 {
|
|
649 int i;
|
|
650
|
|
651 for (i = 0; i < table_size; i++)
|
|
652 if (code == table[i].code)
|
|
653 return build_string (table[i].string);
|
|
654 return Qnil;
|
|
655 }
|
|
656
|
|
657 static Lisp_Object
|
|
658 sublangcode_to_lang (int lang, int sublang, struct lang_to_string *table,
|
|
659 int table_size)
|
|
660 {
|
|
661 int i;
|
|
662 int found_lang = 0;
|
|
663
|
|
664 for (i = 0; i < table_size; i++)
|
|
665 {
|
|
666 if (found_lang)
|
|
667 {
|
|
668 if (!table[i].string)
|
|
669 break;
|
|
670 if (sublang == table[i].code)
|
|
671 return build_string (table[i].string);
|
|
672 }
|
|
673 else if (!table[i].string && lang == table[i].code)
|
|
674 found_lang = 1;
|
|
675 }
|
|
676
|
|
677 switch (sublang)
|
|
678 {
|
|
679 case SUBLANG_NEUTRAL:
|
|
680 return build_string ("NEUTRAL");
|
|
681 case SUBLANG_DEFAULT:
|
|
682 return build_string ("DEFAULT");
|
|
683 case SUBLANG_SYS_DEFAULT:
|
|
684 return build_string ("SYS_DEFAULT");
|
|
685 }
|
|
686
|
|
687 return Qnil;
|
|
688 }
|
|
689
|
|
690 static LCID
|
|
691 locale_to_lcid (Lisp_Object locale)
|
|
692 {
|
|
693 int langcode, sublangcode;
|
|
694 Lisp_Object lang, sublang;
|
|
695
|
|
696 if (STRINGP (locale))
|
|
697 {
|
|
698 lang = locale;
|
|
699 sublang = Qnil;
|
|
700 }
|
|
701 else if (CONSP (locale))
|
|
702 {
|
|
703 CHECK_STRING (XCAR (locale));
|
|
704 CHECK_STRING (XCDR (locale));
|
|
705 lang = XCAR (locale);
|
|
706 sublang = XCDR (locale);
|
|
707 }
|
|
708 else
|
|
709 invalid_argument ("Locale must be LANG or (LANG . SUBLANG)", locale);
|
|
710
|
|
711 langcode = lang_to_langcode (lang, lang_to_string_table,
|
|
712 countof (lang_to_string_table));
|
|
713
|
|
714 if (langcode < 0)
|
|
715 invalid_constant ("Unrecognized language", lang);
|
|
716
|
|
717 if (!NILP (sublang))
|
|
718 {
|
|
719 sublangcode = sublang_to_langcode (sublang, sublang_to_string_table,
|
|
720 countof (sublang_to_string_table));
|
|
721 if (sublangcode < 0)
|
|
722 invalid_constant ("Unrecognized sublanguage", sublang);
|
|
723 }
|
|
724 else
|
|
725 sublangcode = SUBLANG_DEFAULT;
|
|
726
|
|
727 return MAKELCID (MAKELANGID (langcode, sublangcode),
|
|
728 SORT_DEFAULT);
|
|
729 }
|
|
730
|
|
731 static Lisp_Object
|
|
732 lcid_to_locale (LCID lcid)
|
|
733 {
|
|
734 int langid = LANGIDFROMLCID (lcid);
|
|
735 int langcode = PRIMARYLANGID (langid);
|
|
736 int sublangcode = SUBLANGID (langid);
|
|
737
|
|
738 return Fcons (langcode_to_lang (langcode, lang_to_string_table,
|
|
739 countof (lang_to_string_table)),
|
|
740 sublangcode_to_lang (langcode, sublangcode,
|
|
741 sublang_to_string_table,
|
|
742 countof (sublang_to_string_table)));
|
|
743 }
|
|
744
|
|
745 int
|
|
746 mswindows_locale_to_code_page (LCID lcid)
|
|
747 {
|
|
748 char codepagestr[10];
|
|
749
|
|
750 GetLocaleInfoA (lcid, LOCALE_IDEFAULTANSICODEPAGE, codepagestr, 10);
|
|
751 return atoi (codepagestr);
|
|
752 }
|
|
753
|
|
754 int
|
|
755 mswindows_locale_to_oem_code_page (LCID lcid)
|
|
756 {
|
|
757 char codepagestr[10];
|
|
758
|
|
759 GetLocaleInfoA (lcid, LOCALE_IDEFAULTCODEPAGE, codepagestr, 10);
|
|
760 return atoi (codepagestr);
|
|
761 }
|
|
762
|
|
763 static void
|
|
764 set_current_lcid (LCID lcid)
|
|
765 {
|
|
766 int cp;
|
|
767
|
|
768 /* This will fail under Win9x, so we remember our own locale rather than
|
|
769 consulting GetThreadLocale. */
|
|
770 SetThreadLocale (lcid);
|
|
771 current_locale = lcid;
|
|
772 cp = mswindows_locale_to_code_page (lcid);
|
|
773 #ifndef NO_EXT_MULTIBYTE_FEATURES
|
|
774 _setmbcp (cp);
|
|
775 #endif
|
|
776 }
|
|
777
|
|
778 DEFUN ("mswindows-set-current-locale", Fmswindows_set_current_locale,
|
|
779 1, 1, 0, /*
|
|
780 Set the current MS Windows locale.
|
|
781
|
|
782 LOCALE should a language string, or a cons (LANG . SUBLANG).
|
|
783 If SUBLANG is omitted, "SUBLANG_DEFAULT" is used.
|
|
784
|
|
785 Recognized language names are
|
|
786 (some may not be recognized if the compiler is older than VC++ 6.0)
|
|
787
|
|
788 "AFRIKAANS"
|
|
789 "ALBANIAN"
|
|
790 "ARABIC"
|
|
791 "ARMENIAN"
|
|
792 "ASSAMESE"
|
|
793 "AZERI"
|
|
794 "BASQUE"
|
|
795 "BELARUSIAN"
|
|
796 "BENGALI"
|
|
797 "BULGARIAN"
|
|
798 "CATALAN"
|
|
799 "CHINESE"
|
|
800 "CROATIAN"
|
|
801 "CZECH"
|
|
802 "DANISH"
|
|
803 "DUTCH"
|
|
804 "ENGLISH"
|
|
805 "ESTONIAN"
|
|
806 "FAEROESE"
|
|
807 "FARSI"
|
|
808 "FINNISH"
|
|
809 "FRENCH"
|
|
810 "GEORGIAN"
|
|
811 "GERMAN"
|
|
812 "GREEK"
|
|
813 "GUJARATI"
|
|
814 "HEBREW"
|
|
815 "HINDI"
|
|
816 "HUNGARIAN"
|
|
817 "ICELANDIC"
|
|
818 "INDONESIAN"
|
|
819 "ITALIAN"
|
|
820 "JAPANESE"
|
|
821 "KANNADA"
|
|
822 "KASHMIRI"
|
|
823 "KAZAK"
|
|
824 "KONKANI"
|
|
825 "KOREAN"
|
|
826 "LATVIAN"
|
|
827 "LITHUANIAN"
|
|
828 "MACEDONIAN"
|
|
829 "MALAY"
|
|
830 "MALAYALAM"
|
|
831 "MANIPURI"
|
|
832 "MARATHI"
|
|
833 "NEPALI"
|
|
834 "NEUTRAL"
|
|
835 "NORWEGIAN"
|
|
836 "ORIYA"
|
|
837 "POLISH"
|
|
838 "PORTUGUESE"
|
|
839 "PUNJABI"
|
|
840 "ROMANIAN"
|
|
841 "RUSSIAN"
|
|
842 "SANSKRIT"
|
|
843 "SERBIAN"
|
|
844 "SINDHI"
|
|
845 "SLOVAK"
|
|
846 "SLOVENIAN"
|
|
847 "SPANISH"
|
|
848 "SWAHILI"
|
|
849 "SWEDISH"
|
|
850 "TAMIL"
|
|
851 "TATAR"
|
|
852 "TELUGU"
|
|
853 "THAI"
|
|
854 "TURKISH"
|
|
855 "UKRAINIAN"
|
|
856 "URDU"
|
|
857 "UZBEK"
|
|
858 "VIETNAMESE"
|
|
859
|
|
860 Recognized sub-language names are
|
|
861 (some may not be recognized if the compiler is older than VC++ 6.0)
|
|
862
|
|
863 "ARABIC_ALGERIA"
|
|
864 "ARABIC_BAHRAIN"
|
|
865 "ARABIC_EGYPT"
|
|
866 "ARABIC_IRAQ"
|
|
867 "ARABIC_JORDAN"
|
|
868 "ARABIC_KUWAIT"
|
|
869 "ARABIC_LEBANON"
|
|
870 "ARABIC_LIBYA"
|
|
871 "ARABIC_MOROCCO"
|
|
872 "ARABIC_OMAN"
|
|
873 "ARABIC_QATAR"
|
|
874 "ARABIC_SAUDI_ARABIA"
|
|
875 "ARABIC_SYRIA"
|
|
876 "ARABIC_TUNISIA"
|
|
877 "ARABIC_UAE"
|
|
878 "ARABIC_YEMEN"
|
|
879 "AZERI_CYRILLIC"
|
|
880 "AZERI_LATIN"
|
|
881 "CHINESE_HONGKONG"
|
|
882 "CHINESE_MACAU"
|
|
883 "CHINESE_SIMPLIFIED"
|
|
884 "CHINESE_SINGAPORE"
|
|
885 "CHINESE_TRADITIONAL"
|
|
886 "DEFAULT"
|
|
887 "DUTCH"
|
|
888 "DUTCH_BELGIAN"
|
|
889 "ENGLISH_AUS"
|
|
890 "ENGLISH_BELIZE"
|
|
891 "ENGLISH_CAN"
|
|
892 "ENGLISH_CARIBBEAN"
|
|
893 "ENGLISH_EIRE"
|
|
894 "ENGLISH_JAMAICA"
|
|
895 "ENGLISH_NZ"
|
|
896 "ENGLISH_PHILIPPINES"
|
|
897 "ENGLISH_SOUTH_AFRICA"
|
|
898 "ENGLISH_TRINIDAD"
|
|
899 "ENGLISH_UK"
|
|
900 "ENGLISH_US"
|
|
901 "ENGLISH_ZIMBABWE"
|
|
902 "FRENCH"
|
|
903 "FRENCH_BELGIAN"
|
|
904 "FRENCH_CANADIAN"
|
|
905 "FRENCH_LUXEMBOURG"
|
|
906 "FRENCH_MONACO"
|
|
907 "FRENCH_SWISS"
|
|
908 "GERMAN"
|
|
909 "GERMAN_AUSTRIAN"
|
|
910 "GERMAN_LIECHTENSTEIN"
|
|
911 "GERMAN_LUXEMBOURG"
|
|
912 "GERMAN_SWISS"
|
|
913 "ITALIAN"
|
|
914 "ITALIAN_SWISS"
|
|
915 "KASHMIRI_INDIA"
|
|
916 "KOREAN"
|
|
917 "KOREAN_JOHAB" (NOTE: omitted in Visual C++ 6.0 and later)
|
|
918 "LITHUANIAN"
|
|
919 "LITHUANIAN_CLASSIC"
|
|
920 "MALAY_BRUNEI_DARUSSALAM"
|
|
921 "MALAY_MALAYSIA"
|
|
922 "NEPALI_INDIA"
|
|
923 "NEUTRAL"
|
|
924 "NORWEGIAN_BOKMAL"
|
|
925 "NORWEGIAN_NYNORSK"
|
|
926 "PORTUGUESE"
|
|
927 "PORTUGUESE_BRAZILIAN"
|
|
928 "SERBIAN_CYRILLIC"
|
|
929 "SERBIAN_LATIN"
|
|
930 "SPANISH"
|
|
931 "SPANISH_ARGENTINA"
|
|
932 "SPANISH_BOLIVIA"
|
|
933 "SPANISH_CHILE"
|
|
934 "SPANISH_COLOMBIA"
|
|
935 "SPANISH_COSTA_RICA"
|
|
936 "SPANISH_DOMINICAN_REPUBLIC"
|
|
937 "SPANISH_ECUADOR"
|
|
938 "SPANISH_EL_SALVADOR"
|
|
939 "SPANISH_GUATEMALA"
|
|
940 "SPANISH_HONDURAS"
|
|
941 "SPANISH_MEXICAN"
|
|
942 "SPANISH_MODERN"
|
|
943 "SPANISH_NICARAGUA"
|
|
944 "SPANISH_PANAMA"
|
|
945 "SPANISH_PARAGUAY"
|
|
946 "SPANISH_PERU"
|
|
947 "SPANISH_PUERTO_RICO"
|
|
948 "SPANISH_URUGUAY"
|
|
949 "SPANISH_VENEZUELA"
|
|
950 "SWEDISH"
|
|
951 "SWEDISH_FINLAND"
|
|
952 "SYS_DEFAULT"
|
|
953 "URDU_INDIA"
|
|
954 "URDU_PAKISTAN"
|
|
955 "UZBEK_CYRILLIC"
|
|
956 "UZBEK_LATIN"
|
|
957 */
|
|
958 (locale))
|
|
959 {
|
|
960 LCID lcid = locale_to_lcid (locale);
|
|
961
|
|
962 set_current_lcid (lcid);
|
|
963 return Qnil;
|
|
964 }
|
|
965
|
|
966 #ifdef DEBUG_XEMACS
|
|
967
|
872
|
968 int getacp (void);
|
771
|
969 int
|
|
970 getacp (void)
|
|
971 {
|
|
972 return GetACP ();
|
|
973 }
|
|
974
|
|
975 #endif /* DEBUG_XEMACS */
|
|
976
|
|
977 LCID
|
|
978 mswindows_current_locale (void)
|
|
979 {
|
|
980 /* Even if SetThreadLocale() failed, return the right locale anyway */
|
|
981 return current_locale;
|
|
982 }
|
|
983
|
|
984 DEFUN ("mswindows-current-locale", Fmswindows_current_locale,
|
|
985 0, 0, 0, /*
|
|
986 Return the current MS Windows locale.
|
|
987
|
|
988 The return value will be a cons (LANG . SUBLANG). See
|
|
989 `mswindows-set-current-locale' for more info.
|
|
990 */
|
|
991 ())
|
|
992 {
|
|
993 return lcid_to_locale (mswindows_current_locale ());
|
|
994 }
|
|
995
|
|
996 DEFUN ("mswindows-user-default-locale", Fmswindows_user_default_locale,
|
|
997 0, 0, 0, /*
|
|
998 Return the MS Windows user-default locale.
|
|
999 */
|
|
1000 ())
|
|
1001 {
|
|
1002 return lcid_to_locale (GetUserDefaultLCID ());
|
|
1003 }
|
|
1004
|
|
1005 DEFUN ("mswindows-system-default-locale", Fmswindows_system_default_locale,
|
|
1006 0, 0, 0, /*
|
|
1007 Return the MS Windows system-default locale.
|
|
1008 */
|
|
1009 ())
|
|
1010 {
|
|
1011 return lcid_to_locale (GetSystemDefaultLCID ());
|
|
1012 }
|
|
1013
|
|
1014 DEFUN ("mswindows-locale-code-page", Fmswindows_locale_code_page,
|
|
1015 0, 1, 0, /*
|
|
1016 Return the (ANSI) code page of the specified MS Windows locale.
|
|
1017 If LOCALE is nil or omitted, the current locale is used.
|
|
1018 */
|
|
1019 (locale))
|
|
1020 {
|
|
1021 LCID lcid = NILP (locale) ? current_locale : locale_to_lcid (locale);
|
|
1022 return make_int (mswindows_locale_to_code_page (lcid));
|
|
1023 }
|
|
1024
|
|
1025 DEFUN ("mswindows-locale-oem-code-page", Fmswindows_locale_oem_code_page,
|
|
1026 0, 1, 0, /*
|
|
1027 Return the OEM code page of the specified MS Windows locale.
|
|
1028 If LOCALE is nil or omitted, the current locale is used.
|
|
1029 */
|
|
1030 (locale))
|
|
1031 {
|
|
1032 LCID lcid = NILP (locale) ? current_locale : locale_to_lcid (locale);
|
|
1033 return make_int (mswindows_locale_to_oem_code_page (lcid));
|
|
1034 }
|
|
1035
|
|
1036 static DWORD
|
2367
|
1037 int_from_hex (Ascbyte *s)
|
771
|
1038 {
|
|
1039 DWORD val = 0;
|
2367
|
1040 static Ascbyte hex[] = "0123456789abcdefABCDEF";
|
|
1041 Ascbyte *p;
|
771
|
1042
|
|
1043 while (*s && (p = strchr (hex, *s)) != NULL)
|
|
1044 {
|
|
1045 int digit = p - hex;
|
|
1046 if (digit > 15)
|
|
1047 digit -= 6;
|
|
1048 val = val * 16 + digit;
|
|
1049 s++;
|
|
1050 }
|
|
1051 return val;
|
|
1052 }
|
|
1053
|
|
1054 /* We need to build a global list, since the EnumSystemLocale callback
|
|
1055 function isn't given a context pointer. */
|
|
1056 static Lisp_Object Vmswindows_valid_locales;
|
|
1057
|
|
1058 static BOOL CALLBACK
|
2367
|
1059 enum_locale_fn (Ascbyte *localeNum)
|
771
|
1060 {
|
|
1061 DWORD id = int_from_hex (localeNum);
|
|
1062 Vmswindows_valid_locales =
|
|
1063 Fcons (lcid_to_locale ((LCID) id), Vmswindows_valid_locales);
|
|
1064 return TRUE;
|
|
1065 }
|
|
1066
|
|
1067 DEFUN ("mswindows-supported-locales", Fmswindows_supported_locales,
|
|
1068 0, 0, 0, /*
|
|
1069 Return a list of the supported MS Windows locales on this system.
|
|
1070 */
|
|
1071 ())
|
|
1072 {
|
|
1073 Vmswindows_valid_locales = Qnil;
|
|
1074
|
|
1075 /* Use the ANSI version because the return value is just a hex number. */
|
|
1076 EnumSystemLocalesA (enum_locale_fn, LCID_SUPPORTED);
|
|
1077
|
|
1078 Vmswindows_valid_locales = Fnreverse (Vmswindows_valid_locales);
|
|
1079 return Vmswindows_valid_locales;
|
|
1080 }
|
|
1081
|
|
1082 /************************************************************************/
|
|
1083 /* Mule functions */
|
|
1084 /************************************************************************/
|
|
1085
|
|
1086 DEFUN ("mswindows-charset-code-page",
|
|
1087 Fmswindows_charset_code_page, 1, 1, 0, /*
|
|
1088 Return the code page for the CHARSET.
|
|
1089
|
|
1090 #### This function may be changed in the near future.
|
|
1091
|
|
1092 Currently defined Windows code pages include (along with their status
|
|
1093 as Ansi, OEM, Mac, EBCDIC, or some combination):
|
|
1094
|
|
1095 EBCDIC 037 EBCDIC
|
|
1096 OEM 437 MS-DOS United States
|
|
1097 EBCDIC 500 EBCDIC "500V1"
|
|
1098 OEM 708 Arabic (ASMO 708)
|
|
1099 OEM 709 Arabic (ASMO 449+, BCON V4)
|
|
1100 OEM 710 Arabic (Transparent Arabic)
|
|
1101 OEM 720 Arabic (Transparent ASMO)
|
|
1102 OEM 737 Greek (formerly 437G)
|
|
1103 OEM 775 Baltic
|
|
1104 OEM 850 MS-DOS Multilingual (Latin I)
|
|
1105 OEM 852 MS-DOS Slavic (Latin II)
|
|
1106 OEM 855 IBM Cyrillic (primarily Russian)
|
|
1107 OEM 857 IBM Turkish
|
|
1108 OEM 860 MS-DOS Portuguese
|
|
1109 OEM 861 MS-DOS Icelandic
|
|
1110 OEM 862 Hebrew
|
|
1111 OEM 863 MS-DOS Canadian-French
|
|
1112 OEM 864 Arabic
|
|
1113 OEM 865 MS-DOS Nordic
|
|
1114 OEM 866 MS-DOS Russian
|
|
1115 OEM 869 IBM Modern Greek
|
|
1116 Ansi/OEM 874 Thai
|
|
1117 EBCDIC 875 EBCDIC
|
|
1118 Ansi/OEM 932 Japanese
|
|
1119 Ansi/OEM 936 Chinese (PRC, Singapore)
|
|
1120 Ansi/OEM 949 Korean
|
|
1121 Ansi/OEM 950 Chinese (Taiwan; Hong Kong SAR, PRC)
|
|
1122 EBCDIC 1026 EBCDIC
|
|
1123 ANSI 1200 Unicode (BMP of ISO 10646)
|
|
1124 ANSI 1250 Windows 3.1 Eastern European
|
|
1125 ANSI 1251 Windows 3.1 Cyrillic
|
|
1126 ANSI 1252 Windows 3.1 US (ANSI)
|
|
1127 ANSI 1253 Windows 3.1 Greek
|
|
1128 ANSI 1254 Windows 3.1 Turkish
|
|
1129 ANSI 1255 Hebrew
|
|
1130 ANSI 1256 Arabic
|
|
1131 ANSI 1257 Baltic
|
|
1132 ANSI 1258 VietNam
|
|
1133 Ansi/OEM 1361 Korean (Johab)
|
|
1134 Mac 10000 Macintosh Roman
|
|
1135 Mac 10001 Macintosh Japanese
|
|
1136 Mac 10006 Macintosh Greek I
|
|
1137 Mac 10007 Macintosh Cyrillic
|
|
1138 Mac 10029 Macintosh Latin 2
|
|
1139 Mac 10079 Macintosh Icelandic
|
|
1140 Mac 10081 Macintosh Turkish
|
|
1141
|
|
1142 A code page is a set of characters, along with an enumeration of these
|
|
1143 characters and an encoding of them in a byte stream. Thus, in XEmacs
|
|
1144 parlance it defines both a "charset" and a "coding system" for this
|
|
1145 charset. Traditional encodings are either simple one-byte encodings, or
|
|
1146 combination one-byte/two-byte encodings (aka MBCS encodings, where MBCS
|
|
1147 stands for "Multibyte Character Set") with the following properties:
|
|
1148
|
|
1149 -- all characters are encoded as a one-byte or two-byte sequence
|
|
1150 -- the encoding is stateless (non-modal)
|
|
1151 -- the lower 128 bytes are compatible with ASCII
|
|
1152 -- in the higher bytes, the value of the first byte ("lead byte")
|
|
1153 determines whether a second byte follows
|
|
1154 -- the values used for second bytes may overlap those used for first bytes,
|
|
1155 and (in some encodings) include values in the low half; thus, moving
|
|
1156 backwards is hard, and pure-ASCII algorithms (e.g. finding the next slash)
|
|
1157 will fail unless rewritten to be MBCS-aware (neither of these problems
|
|
1158 exist in UTF-8 or in the XEmacs internal string encoding)
|
|
1159
|
|
1160 Recent code pages, however, do not necessarily follow these properties --
|
|
1161 code pages have been expanded to include arbitrary encodings, such as UTF-8
|
|
1162 \(may have more than two bytes per character) and ISO-2022-JP (complex modal
|
|
1163 encoding).
|
|
1164
|
|
1165 Every locale has four associated code pages: ANSI (an international
|
|
1166 standard or some Microsoft-created approximation; the native code page
|
|
1167 under Windows), OEM (a DOS encoding, still used in the FAT file system),
|
|
1168 Mac (an encoding used on the Macintosh) and EBCDIC (a non-ASCII-compatible
|
|
1169 encoding used on IBM mainframes, originally based on the BCD or
|
|
1170 "binary-coded decimal" encoding of numbers). All code pages associated
|
|
1171 with a locale follow (as far as I know) the properties listed above for
|
|
1172 traditional code pages.
|
|
1173 */
|
|
1174 (charset))
|
|
1175 {
|
|
1176 charset = Fget_charset (charset);
|
|
1177 return Fgethash (charset, Vmswindows_charset_code_page_table, Qnil);
|
|
1178 }
|
|
1179
|
|
1180 DEFUN ("mswindows-set-charset-code-page",
|
|
1181 Fmswindows_set_charset_code_page, 2, 2, 0, /*
|
|
1182 Set the CODE-PAGE for the CHARSET.
|
|
1183
|
|
1184 #### This function may be changed once full Unicode support is present.
|
|
1185 */
|
|
1186 (charset, code_page))
|
|
1187 {
|
|
1188 charset = Fget_charset (charset);
|
|
1189 CHECK_INT (code_page);
|
|
1190 Fputhash (charset, code_page, Vmswindows_charset_code_page_table);
|
|
1191 return Qnil;
|
|
1192 }
|
|
1193
|
|
1194 Lisp_Object
|
|
1195 mswindows_get_code_page_charset (int code_page)
|
|
1196 {
|
|
1197 Lisp_Object charset_tail;
|
|
1198 Lisp_Object charset = Qunbound;
|
|
1199
|
|
1200 LIST_LOOP (charset_tail, Fcharset_list ())
|
|
1201 {
|
|
1202 Lisp_Object charset_code_page;
|
|
1203
|
|
1204 charset_code_page = Fmswindows_charset_code_page (XCAR (charset_tail));
|
|
1205 if (INTP (charset_code_page) &&
|
|
1206 code_page == XINT (charset_code_page))
|
|
1207 {
|
|
1208 charset = Fget_charset (XCAR (charset_tail));
|
|
1209 break;
|
|
1210 }
|
|
1211 }
|
|
1212 return charset;
|
|
1213 }
|
|
1214
|
872
|
1215 DEFUN ("mswindows-charset-registry",
|
|
1216 Fmswindows_charset_registry, 1, 1, 0, /*
|
|
1217 Return the registry for the CHARSET.
|
|
1218 This is the last item in an MS Windows font spec.
|
|
1219
|
|
1220 #### This function may be changed in the near future.
|
|
1221 */
|
|
1222 (charset))
|
|
1223 {
|
|
1224 charset = Fget_charset (charset);
|
|
1225 return Fgethash (charset, Vmswindows_charset_registry_table, Qnil);
|
|
1226 }
|
|
1227
|
|
1228 DEFUN ("mswindows-set-charset-registry",
|
|
1229 Fmswindows_set_charset_registry, 2, 2, 0, /*
|
|
1230 Set the REGISTRY for the CHARSET.
|
|
1231
|
|
1232 #### This function may be changed once full Unicode support is present.
|
|
1233 */
|
|
1234 (charset, registry))
|
|
1235 {
|
|
1236 charset = Fget_charset (charset);
|
|
1237 CHECK_STRING (registry);
|
|
1238 Fputhash (charset, registry, Vmswindows_charset_registry_table);
|
|
1239 invalidate_charset_font_caches (charset);
|
|
1240 face_property_was_changed (Vdefault_face, Qfont, Qglobal);
|
|
1241 return Qnil;
|
|
1242 }
|
|
1243
|
1111
|
1244 #if 0 /* Unused */
|
|
1245
|
|
1246 static Lisp_Object
|
872
|
1247 mswindows_get_registry_charset (Ibyte *registry)
|
|
1248 {
|
|
1249 Lisp_Object charset_tail;
|
|
1250 Lisp_Object charset = Qunbound;
|
|
1251
|
|
1252 LIST_LOOP (charset_tail, Fcharset_list ())
|
|
1253 {
|
|
1254 Lisp_Object charset_registry;
|
|
1255
|
|
1256 charset_registry = Fmswindows_charset_registry (XCAR (charset_tail));
|
|
1257 if (STRINGP (charset_registry) &&
|
|
1258 !qxestrcasecmp (XSTRING_DATA (charset_registry), registry))
|
|
1259 {
|
|
1260 charset = Fget_charset (XCAR (charset_tail));
|
|
1261 break;
|
|
1262 }
|
|
1263 }
|
|
1264 return charset;
|
|
1265 }
|
|
1266
|
1111
|
1267 #endif /* 0 */
|
|
1268
|
771
|
1269
|
|
1270
|
|
1271 #if 0 /* #### from Emacs 20.6; consider porting */
|
|
1272
|
826
|
1273 DEFUN ("mswindows-get-locale-info", Fmswindows_get_locale_info, 1, 2, 0, /*
|
771
|
1274 Return information about the Windows locale LCID.
|
|
1275 By default, return a three letter locale code which encodes the default
|
|
1276 language as the first two characters, and the country or regionial variant
|
|
1277 as the third letter. For example, ENU refers to `English (United States)',
|
|
1278 while ENC means `English (Canadian)'.
|
|
1279
|
|
1280 If the optional argument LONGFORM is t, the long form of the locale
|
|
1281 name is returned, e.g. `English (United States)' instead; if LONGFORM
|
|
1282 is a number, it is interpreted as an LCTYPE constant and the corresponding
|
|
1283 locale information is returned.
|
|
1284
|
|
1285 If LCID (a 16-bit number) is not a valid locale, the result is nil.
|
|
1286 */
|
|
1287 (lcid, longform))
|
|
1288 {
|
|
1289 int got_abbrev;
|
|
1290 int got_full;
|
|
1291 char abbrev_name[32] = { 0 };
|
|
1292 char full_name[256] = { 0 };
|
|
1293
|
|
1294 CHECK_INT (lcid);
|
|
1295
|
|
1296 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
|
|
1297 return Qnil;
|
|
1298
|
|
1299 if (NILP (longform))
|
|
1300 {
|
|
1301 got_abbrev = GetLocaleInfo (XINT (lcid),
|
|
1302 LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
|
|
1303 abbrev_name, sizeof (abbrev_name));
|
|
1304 if (got_abbrev)
|
|
1305 return build_string (abbrev_name);
|
|
1306 }
|
|
1307 else if (EQ (longform, Qt))
|
|
1308 {
|
|
1309 got_full = GetLocaleInfo (XINT (lcid),
|
|
1310 LOCALE_SLANGUAGE | LOCALE_USE_CP_ACP,
|
|
1311 full_name, sizeof (full_name));
|
|
1312 if (got_full)
|
|
1313 return build_string (full_name);
|
|
1314 }
|
|
1315 else if (NUMBERP (longform))
|
|
1316 {
|
|
1317 got_full = GetLocaleInfo (XINT (lcid),
|
|
1318 XINT (longform),
|
|
1319 full_name, sizeof (full_name));
|
|
1320 if (got_full)
|
|
1321 return make_unibyte_string (full_name, got_full);
|
|
1322 }
|
|
1323
|
|
1324 return Qnil;
|
|
1325 }
|
|
1326
|
|
1327 /* We need to build a global list, since the EnumCodePages callback
|
|
1328 function isn't given a context pointer. */
|
|
1329 Lisp_Object Vmswindows_valid_code_pages;
|
|
1330
|
|
1331 BOOL CALLBACK enum_code_page_fn (LPTSTR codepageNum)
|
|
1332 {
|
|
1333 DWORD id = atoi (codepageNum);
|
|
1334 Vmswindows_valid_code_pages = Fcons (make_int (id), Vmswindows_valid_code_pages);
|
|
1335 return TRUE;
|
|
1336 }
|
|
1337
|
826
|
1338 DEFUN ("mswindows-get-valid-code-pages", Fmswindows_get_valid_code_pages, 0, 0, 0, /*
|
771
|
1339 Return list of all valid Windows code pages.
|
|
1340 */
|
|
1341 ())
|
|
1342 {
|
|
1343 Vmswindows_valid_code_pages = Qnil;
|
|
1344
|
|
1345 EnumSystemCodePages (enum_code_page_fn, CP_SUPPORTED);
|
|
1346
|
|
1347 Vmswindows_valid_code_pages = Fnreverse (Vmswindows_valid_code_pages);
|
|
1348 return Vmswindows_valid_code_pages;
|
|
1349 }
|
|
1350
|
826
|
1351 DEFUN ("mswindows-get-console-code-page", Fmswindows_get_console_code_page, 0, 0, 0, /*
|
771
|
1352 Return current Windows code page for console input.
|
|
1353 */
|
|
1354 ())
|
|
1355 {
|
|
1356 return make_int (GetConsoleCP ());
|
|
1357 }
|
|
1358
|
826
|
1359 DEFUN ("mswindows-set-console-code-page", Fmswindows_set_console_code_page, 1, 1, 0, /*
|
771
|
1360 Make Windows code page CP be the current code page setting for Emacs.
|
|
1361 The code page setting affects keyboard input and display in tty mode.
|
|
1362 If successful, the new CP is returned, otherwise nil.
|
|
1363 */
|
|
1364 (cp))
|
|
1365 {
|
|
1366 CHECK_INT (cp);
|
|
1367
|
|
1368 if (!IsValidCodePage (XINT (cp)))
|
|
1369 return Qnil;
|
|
1370
|
|
1371 if (!SetConsoleCP (XINT (cp)))
|
|
1372 return Qnil;
|
|
1373
|
|
1374 return make_int (GetConsoleCP ());
|
|
1375 }
|
|
1376
|
826
|
1377 DEFUN ("mswindows-get-console-output-code-page", Fmswindows_get_console_output_code_page, 0, 0, 0, /*
|
771
|
1378 Return current Windows code page for console output.
|
|
1379 */
|
|
1380 ())
|
|
1381 {
|
|
1382 return make_int (GetConsoleOutputCP ());
|
|
1383 }
|
|
1384
|
826
|
1385 DEFUN ("mswindows-set-console-output-code-page", Fmswindows_set_console_output_code_page, 1, 1, 0, /*
|
771
|
1386 Make Windows code page CP be the current code page setting for Emacs.
|
|
1387 The code page setting affects keyboard input and display in tty mode.
|
|
1388 If successful, the new CP is returned, otherwise nil.
|
|
1389 */
|
|
1390 (cp))
|
|
1391 {
|
|
1392 CHECK_INT (cp);
|
|
1393
|
|
1394 if (!IsValidCodePage (XINT (cp)))
|
|
1395 return Qnil;
|
|
1396
|
|
1397 if (!SetConsoleOutputCP (XINT (cp)))
|
|
1398 return Qnil;
|
|
1399
|
|
1400 return make_int (GetConsoleOutputCP ());
|
|
1401 }
|
|
1402
|
826
|
1403 DEFUN ("mswindows-get-code-page-charset", Fmswindows_get_code_page_charset, 1, 1, 0, /*
|
771
|
1404 Return charset of code page CP.
|
|
1405 Returns nil if the code page is not valid.
|
|
1406 */
|
|
1407 (cp))
|
|
1408 {
|
|
1409 CHARSETINFO info;
|
|
1410
|
|
1411 CHECK_INT (cp);
|
|
1412
|
|
1413 if (!IsValidCodePage (XINT (cp)))
|
|
1414 return Qnil;
|
|
1415
|
|
1416 if (TranslateCharsetInfo ((DWORD *) XINT (cp), &info, TCI_SRCCODEPAGE))
|
|
1417 return make_int (info.ciCharset);
|
|
1418
|
|
1419 return Qnil;
|
|
1420 }
|
|
1421
|
826
|
1422 DEFUN ("mswindows-get-valid-keyboard-layouts", Fmswindows_get_valid_keyboard_layouts, 0, 0, 0, /*
|
771
|
1423 Return list of Windows keyboard languages and layouts.
|
|
1424 The return value is a list of pairs of language id and layout id.
|
|
1425 */
|
|
1426 ())
|
|
1427 {
|
|
1428 int num_layouts = GetKeyboardLayoutList (0, NULL);
|
2367
|
1429 HKL *layouts = alloca_array (HKL, num_layouts);
|
771
|
1430 Lisp_Object obj = Qnil;
|
|
1431
|
|
1432 if (GetKeyboardLayoutList (num_layouts, layouts) == num_layouts)
|
|
1433 {
|
|
1434 while (--num_layouts >= 0)
|
|
1435 {
|
|
1436 DWORD kl = (DWORD) layouts[num_layouts];
|
|
1437
|
|
1438 obj = Fcons (Fcons (make_int (kl & 0xffff),
|
|
1439 make_int ((kl >> 16) & 0xffff)),
|
|
1440 obj);
|
|
1441 }
|
|
1442 }
|
|
1443
|
|
1444 return obj;
|
|
1445 }
|
|
1446
|
826
|
1447 DEFUN ("mswindows-get-keyboard-layout", Fmswindows_get_keyboard_layout, 0, 0, 0, /*
|
771
|
1448 Return current Windows keyboard language and layout.
|
|
1449 The return value is the cons of the language id and the layout id.
|
|
1450 */
|
|
1451 ())
|
|
1452 {
|
|
1453 DWORD kl = (DWORD) GetKeyboardLayout (dwWindowsThreadId);
|
|
1454
|
|
1455 return Fcons (make_int (kl & 0xffff),
|
|
1456 make_int ((kl >> 16) & 0xffff));
|
|
1457 }
|
|
1458
|
826
|
1459 DEFUN ("mswindows-set-keyboard-layout", Fmswindows_set_keyboard_layout, 1, 1, 0, /*
|
771
|
1460 Make LAYOUT be the current keyboard layout for Emacs.
|
|
1461 The keyboard layout setting affects interpretation of keyboard input.
|
|
1462 If successful, the new layout id is returned, otherwise nil.
|
|
1463 */
|
|
1464 (layout))
|
|
1465 {
|
|
1466 DWORD kl;
|
|
1467
|
|
1468 CHECK_CONS (layout);
|
|
1469 CHECK_INT (XCAR (layout)));
|
|
1470 CHECK_INT (XCDR (layout)));
|
|
1471
|
|
1472 kl = (XINT (XCAR (layout))) & 0xffff)
|
|
1473 | (XINT (XCDR (layout))) << 16);
|
|
1474
|
|
1475 if (!ActivateKeyboardLayout ((HKL) kl, 0))
|
|
1476 return Qnil;
|
|
1477
|
|
1478 return Fmswindows_get_keyboard_layout ();
|
|
1479 }
|
|
1480
|
|
1481 #endif /* 0 */
|
|
1482
|
|
1483
|
|
1484 /* input method functions. */
|
|
1485
|
|
1486 #ifdef HAVE_MS_WINDOWS
|
|
1487
|
|
1488 void
|
|
1489 mswindows_start_ime_composition (struct frame *f)
|
|
1490 {
|
|
1491 COMPOSITIONFORM form;
|
|
1492 HWND hwnd = FRAME_MSWINDOWS_HANDLE (f);
|
|
1493 HIMC himc = ImmGetContext (hwnd);
|
|
1494
|
|
1495 /* Set a position of composition window. */
|
|
1496 xzero (form);
|
|
1497 form.dwStyle = CFS_POINT;
|
|
1498 form.ptCurrentPos.x = FRAME_MSWINDOWS_CURSOR_X (f);
|
|
1499 form.ptCurrentPos.y = FRAME_MSWINDOWS_CURSOR_Y (f);
|
|
1500 ImmSetCompositionWindow (himc, &form);
|
|
1501
|
|
1502 /* Set composition window font same as current face one. */
|
|
1503 {
|
|
1504 LOGFONTW old_logfont;
|
|
1505 CHARSETINFO info;
|
|
1506 Lisp_Object charset;
|
|
1507
|
|
1508 /* Get Mule charset from current ime font charset. */
|
|
1509 qxeImmGetCompositionFont (himc, &old_logfont);
|
|
1510 TranslateCharsetInfo ((DWORD *) (DWORD) old_logfont.lfCharSet, &info,
|
|
1511 TCI_SRCCHARSET);
|
|
1512 charset = mswindows_get_code_page_charset (info.ciACP);
|
|
1513
|
|
1514 if (CHARSETP (charset))
|
|
1515 {
|
|
1516 Lisp_Object window = FRAME_SELECTED_WINDOW (f);
|
|
1517 struct window *w = XWINDOW (window);
|
|
1518 face_index findex = FRAME_MSWINDOWS_CURSOR_FINDEX (f);
|
|
1519 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
|
|
1520 Lisp_Object face_font = FACE_CACHEL_FONT (cachel, charset);
|
|
1521
|
|
1522 if (!FONT_INSTANCEP (face_font))
|
|
1523 face_font =
|
|
1524 ensure_face_cachel_contains_charset (cachel, window, charset);
|
|
1525
|
|
1526 if (!EQ (face_font, Vthe_null_font_instance))
|
|
1527 {
|
|
1528 LOGFONTW new_logfont;
|
|
1529
|
|
1530 /* Get LOGFONT from the face font */
|
|
1531 if (qxeGetObject (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT
|
|
1532 (XFONT_INSTANCE (face_font),
|
|
1533 cachel->underline, cachel->strikethru),
|
|
1534 sizeof (LOGFONTW), (void*) &new_logfont))
|
|
1535 qxeImmSetCompositionFont (himc, &new_logfont);
|
|
1536 }
|
|
1537 }
|
|
1538 }
|
|
1539 ImmReleaseContext (hwnd, himc);
|
|
1540 return;
|
|
1541 }
|
|
1542
|
|
1543 #endif /* HAVE_MS_WINDOWS */
|
|
1544
|
|
1545 #else /* not MULE */
|
|
1546
|
|
1547 int
|
2286
|
1548 mswindows_locale_to_code_page (LCID UNUSED (lcid))
|
771
|
1549 {
|
|
1550 return CP_ACP;
|
|
1551 }
|
|
1552
|
|
1553 #endif /* MULE */
|
|
1554
|
|
1555
|
|
1556 #ifdef CYGWIN
|
|
1557
|
1111
|
1558 /* based on newlib str*() */
|
|
1559
|
|
1560 #ifndef HAVE_WCSCMP
|
|
1561
|
|
1562 int
|
|
1563 wcscmp (const wchar_t *s1, const wchar_t *s2)
|
|
1564 {
|
|
1565 while (*s1 != '\0' && *s1 == *s2)
|
|
1566 {
|
|
1567 s1++;
|
|
1568 s2++;
|
|
1569 }
|
|
1570
|
|
1571 return *s1 - *s2;
|
|
1572 }
|
|
1573
|
|
1574 #endif /* not HAVE_WCSCMP */
|
|
1575
|
|
1576 #ifndef HAVE_WCSLEN
|
|
1577
|
|
1578 size_t
|
|
1579 wcslen (const wchar_t *str)
|
|
1580 {
|
|
1581 const wchar_t *start = str;
|
|
1582
|
|
1583 while (*str)
|
|
1584 str++;
|
|
1585
|
|
1586 return str - start;
|
|
1587 }
|
|
1588
|
|
1589 #endif /* not HAVE_WCSLEN */
|
771
|
1590
|
|
1591 wchar_t *
|
|
1592 wcsncpy (wchar_t *dst0, const wchar_t *src0, size_t count)
|
|
1593 {
|
|
1594 wchar_t *dscan;
|
|
1595 const wchar_t *sscan;
|
|
1596
|
|
1597 dscan = dst0;
|
|
1598 sscan = src0;
|
|
1599 while (count > 0)
|
|
1600 {
|
|
1601 --count;
|
|
1602 if ((*dscan++ = *sscan++) == '\0')
|
|
1603 break;
|
|
1604 }
|
|
1605 while (count-- > 0)
|
|
1606 *dscan++ = '\0';
|
|
1607
|
|
1608 return dst0;
|
|
1609 }
|
|
1610
|
|
1611 wchar_t *
|
|
1612 wcscpy (wchar_t *dst0, const wchar_t *src0)
|
|
1613 {
|
|
1614 wchar_t *s = dst0;
|
|
1615
|
|
1616 while ((*dst0++ = *src0++))
|
|
1617 ;
|
|
1618
|
|
1619 return s;
|
|
1620 }
|
|
1621
|
|
1622 wchar_t *
|
|
1623 wcsdup (const wchar_t *str)
|
|
1624 {
|
|
1625 int len = wcslen (str) + 1;
|
2367
|
1626 wchar_t *val = xnew_array (wchar_t, len);
|
771
|
1627
|
|
1628 if (val == 0) return 0;
|
|
1629 return (wchar_t *) memcpy (val, str, len * sizeof (wchar_t));
|
|
1630 }
|
|
1631
|
|
1632 #endif /* CYGWIN */
|
|
1633
|
|
1634
|
|
1635 /************************************************************************/
|
|
1636 /* MS Windows multibyte-to-unicode methods */
|
|
1637 /************************************************************************/
|
|
1638
|
|
1639 enum mswindows_multibyte_cp_type
|
|
1640 {
|
|
1641 MULTIBYTE_ANSI,
|
|
1642 MULTIBYTE_OEM,
|
|
1643 MULTIBYTE_EBCDIC,
|
|
1644 MULTIBYTE_MAC
|
|
1645 };
|
|
1646
|
|
1647 enum mswindows_multibyte_locale_type
|
|
1648 {
|
|
1649 MULTIBYTE_SPECIFIED_LOCALE,
|
|
1650 MULTIBYTE_SPECIFIED_CODE_PAGE,
|
|
1651 MULTIBYTE_CURRENT,
|
|
1652 MULTIBYTE_USER_DEFAULT,
|
|
1653 MULTIBYTE_SYSTEM_DEFAULT
|
|
1654 };
|
|
1655
|
|
1656 struct mswindows_multibyte_to_unicode_coding_system
|
|
1657 {
|
|
1658 enum mswindows_multibyte_cp_type cp_type;
|
|
1659 enum mswindows_multibyte_locale_type locale_type;
|
|
1660 LCID locale; /* if locale_type is MULTIBYTE_SPECIFIED_LOCALE */
|
|
1661 int cp; /* if locale_type is MULTIBYTE_SPECIFIED_CODE_PAGE */
|
|
1662 };
|
|
1663
|
|
1664 struct mswindows_multibyte_to_unicode_coding_stream
|
|
1665 {
|
|
1666 int partial_byte;
|
|
1667 int partial_byte_present;
|
|
1668 int cp;
|
|
1669 };
|
|
1670
|
1204
|
1671 static const struct memory_description
|
771
|
1672 mswindows_multibyte_to_unicode_coding_system_description[] = {
|
|
1673 { XD_END }
|
|
1674 };
|
|
1675
|
1204
|
1676 DEFINE_CODING_SYSTEM_TYPE_WITH_DATA (mswindows_multibyte_to_unicode);
|
|
1677
|
771
|
1678 static void
|
|
1679 mswindows_multibyte_to_unicode_init (Lisp_Object codesys)
|
|
1680 {
|
|
1681 struct mswindows_multibyte_to_unicode_coding_system *data =
|
|
1682 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte_to_unicode);
|
|
1683
|
|
1684 data->cp_type = MULTIBYTE_ANSI;
|
|
1685 data->locale_type = MULTIBYTE_CURRENT;
|
|
1686 }
|
|
1687
|
|
1688 static Lisp_Object
|
2286
|
1689 lcid_to_locale_mule_or_no (LCID USED_IF_MULE (lcid))
|
771
|
1690 {
|
|
1691 #ifdef MULE
|
|
1692 return lcid_to_locale (lcid);
|
|
1693 #else
|
|
1694 return Fcons (build_string ("NEUTRAL"), build_string ("DEFAULT"));
|
|
1695 #endif
|
|
1696 }
|
|
1697
|
|
1698 static int
|
2286
|
1699 determine_code_page (Lisp_Object USED_IF_MULE (codesys))
|
771
|
1700 {
|
|
1701 #ifdef MULE
|
|
1702 LCID locale;
|
|
1703 struct mswindows_multibyte_to_unicode_coding_system *data =
|
|
1704 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte_to_unicode);
|
|
1705
|
|
1706 switch (data->locale_type)
|
|
1707 {
|
|
1708 case MULTIBYTE_SPECIFIED_CODE_PAGE:
|
|
1709 return data->cp;
|
|
1710 case MULTIBYTE_SPECIFIED_LOCALE:
|
|
1711 locale = data->locale; break;
|
|
1712 case MULTIBYTE_CURRENT:
|
|
1713 locale = mswindows_current_locale (); break;
|
|
1714 case MULTIBYTE_USER_DEFAULT:
|
|
1715 locale = GetUserDefaultLCID (); break;
|
|
1716 case MULTIBYTE_SYSTEM_DEFAULT:
|
|
1717 locale = GetSystemDefaultLCID (); break;
|
|
1718 default:
|
2500
|
1719 ABORT (); locale = 0;
|
771
|
1720 }
|
|
1721
|
|
1722 switch (data->cp_type)
|
|
1723 {
|
|
1724 case MULTIBYTE_ANSI:
|
|
1725 return mswindows_locale_to_code_page (locale);
|
|
1726 case MULTIBYTE_OEM:
|
|
1727 return mswindows_locale_to_oem_code_page (locale);
|
|
1728 case MULTIBYTE_EBCDIC:
|
|
1729 #ifdef LOCALE_IDEFAULTEBCDICCODEPAGE /* Doesn't exist under Cygwin */
|
|
1730 {
|
|
1731 char codepagestr[10];
|
|
1732 GetLocaleInfoA (locale, LOCALE_IDEFAULTEBCDICCODEPAGE, codepagestr,
|
|
1733 10);
|
|
1734 return atoi (codepagestr);
|
|
1735 }
|
|
1736 #else
|
|
1737 invalid_operation ("Unable to determine EBCDIC code page for locale",
|
|
1738 lcid_to_locale (locale));
|
|
1739 return 0;
|
|
1740 #endif
|
|
1741 case MULTIBYTE_MAC:
|
|
1742 #ifdef LOCALE_IDEFAULTMACCODEPAGE /* Doesn't exist under Cygwin */
|
|
1743 {
|
|
1744 char codepagestr[10];
|
|
1745 GetLocaleInfoA (locale, LOCALE_IDEFAULTMACCODEPAGE, codepagestr,
|
|
1746 10);
|
|
1747 return atoi (codepagestr);
|
|
1748 }
|
|
1749 #else
|
|
1750 invalid_operation ("Unable to determine Mac code page for locale",
|
|
1751 lcid_to_locale (locale));
|
|
1752 return 0;
|
|
1753 #endif
|
|
1754 default:
|
2500
|
1755 ABORT (); return 0;
|
771
|
1756 }
|
|
1757 #else /* not MULE */
|
|
1758 return CP_ACP;
|
|
1759 #endif
|
|
1760 }
|
|
1761
|
|
1762 static int
|
|
1763 mswindows_multibyte_to_unicode_putprop (Lisp_Object codesys,
|
|
1764 Lisp_Object key,
|
|
1765 Lisp_Object value)
|
|
1766 {
|
|
1767 struct mswindows_multibyte_to_unicode_coding_system *data =
|
|
1768 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte_to_unicode);
|
|
1769
|
|
1770 if (EQ (key, Qcode_page))
|
|
1771 {
|
|
1772 if (EQ (value, Qansi))
|
|
1773 data->cp_type = MULTIBYTE_ANSI;
|
|
1774 else if (EQ (value, Qoem))
|
|
1775 data->cp_type = MULTIBYTE_OEM;
|
|
1776 else if (EQ (value, Qebcdic))
|
|
1777 data->cp_type = MULTIBYTE_EBCDIC;
|
|
1778 else if (EQ (value, Qmac))
|
|
1779 data->cp_type = MULTIBYTE_MAC;
|
|
1780 else
|
|
1781 {
|
|
1782 CHECK_NATNUM (value);
|
|
1783 data->locale_type = MULTIBYTE_SPECIFIED_CODE_PAGE;
|
|
1784 data->cp = XINT (value);
|
|
1785 }
|
|
1786 }
|
|
1787 else if (EQ (key, Qlocale))
|
|
1788 {
|
|
1789 if (EQ (value, Qcurrent))
|
|
1790 data->locale_type = MULTIBYTE_CURRENT;
|
|
1791 else if (EQ (value, Quser_default))
|
|
1792 data->locale_type = MULTIBYTE_USER_DEFAULT;
|
|
1793 else if (EQ (value, Qsystem_default))
|
|
1794 data->locale_type = MULTIBYTE_SYSTEM_DEFAULT;
|
|
1795 else
|
|
1796 {
|
|
1797 data->locale_type = MULTIBYTE_SPECIFIED_LOCALE;
|
|
1798 #ifdef MULE
|
|
1799 data->locale = locale_to_lcid (value);
|
|
1800 #else
|
|
1801 data->locale = 0;
|
|
1802 #endif
|
|
1803 }
|
|
1804 }
|
|
1805 else
|
|
1806 return 0;
|
|
1807 return 1;
|
|
1808 }
|
|
1809
|
|
1810 static Lisp_Object
|
|
1811 mswindows_multibyte_to_unicode_getprop (Lisp_Object coding_system,
|
|
1812 Lisp_Object prop)
|
|
1813 {
|
|
1814 struct mswindows_multibyte_to_unicode_coding_system *data =
|
|
1815 XCODING_SYSTEM_TYPE_DATA (coding_system, mswindows_multibyte_to_unicode);
|
|
1816
|
|
1817 if (EQ (prop, Qcode_page))
|
|
1818 {
|
|
1819 if (data->locale_type == MULTIBYTE_SPECIFIED_CODE_PAGE)
|
|
1820 return make_int (data->cp);
|
|
1821 else
|
|
1822 switch (data->cp_type)
|
|
1823 {
|
|
1824 case MULTIBYTE_ANSI: return Qansi;
|
|
1825 case MULTIBYTE_OEM: return Qoem;
|
|
1826 case MULTIBYTE_EBCDIC: return Qebcdic;
|
|
1827 case MULTIBYTE_MAC: return Qmac;
|
2500
|
1828 default: ABORT ();
|
771
|
1829 }
|
|
1830 }
|
|
1831 else if (EQ (prop, Qlocale))
|
|
1832 {
|
|
1833 switch (data->locale_type)
|
|
1834 {
|
|
1835 case MULTIBYTE_CURRENT: return Qcurrent;
|
|
1836 case MULTIBYTE_USER_DEFAULT: return Quser_default;
|
|
1837 case MULTIBYTE_SYSTEM_DEFAULT: return Qsystem_default;
|
|
1838 case MULTIBYTE_SPECIFIED_LOCALE:
|
|
1839 return lcid_to_locale_mule_or_no (data->locale);
|
|
1840
|
|
1841 case MULTIBYTE_SPECIFIED_CODE_PAGE:
|
|
1842 return Qnil;
|
2500
|
1843 default: ABORT ();
|
771
|
1844 }
|
|
1845 }
|
|
1846
|
|
1847 return Qunbound;
|
|
1848 }
|
|
1849
|
|
1850 static void
|
2286
|
1851 mswindows_multibyte_to_unicode_print (Lisp_Object cs, Lisp_Object printcharfun,
|
|
1852 int UNUSED (escapeflag))
|
771
|
1853 {
|
|
1854 struct mswindows_multibyte_to_unicode_coding_system *data =
|
|
1855 XCODING_SYSTEM_TYPE_DATA (cs, mswindows_multibyte_to_unicode);
|
|
1856
|
826
|
1857 write_c_string (printcharfun, "(");
|
771
|
1858 if (data->locale_type == MULTIBYTE_SPECIFIED_CODE_PAGE)
|
|
1859 print_internal (make_int (data->cp), printcharfun, 1);
|
|
1860 else
|
|
1861 {
|
800
|
1862 write_fmt_string_lisp (printcharfun, "%s, ", 1, mswindows_multibyte_to_unicode_getprop (cs, Qlocale));
|
|
1863 print_internal (mswindows_multibyte_to_unicode_getprop (cs, Qcode_page), printcharfun, 0);
|
771
|
1864 }
|
826
|
1865 write_c_string (printcharfun, ")");
|
771
|
1866 }
|
|
1867
|
2367
|
1868 /* ----------------------------------------------------------------------- */
|
|
1869 /* Unicode/Multibyte converters */
|
|
1870 /* ----------------------------------------------------------------------- */
|
|
1871
|
771
|
1872 /* Convert multibyte to Unicode according to the specified code page
|
|
1873 and return the value as a malloc()ed string. This currently exists
|
|
1874 because the TO_INTERNAL_FORMAT() mechanism -- the normal way to do
|
|
1875 such conversions -- has no way of passing in a parameter to control
|
|
1876 the operation. We could use a global variable to pass this value
|
|
1877 in, but that runs the risk of causing problems due to reentrancy.
|
|
1878 (You might say, yeah, right, how can TO_INTERNAL_FORMAT() get
|
|
1879 called recursively merely when I'm doing a simple conversion
|
|
1880 operation? It turns out this can and does happen, consistently, as
|
|
1881 a result of calling QUIT -- it happens consistently for complicated
|
2367
|
1882 reasons outlined in event-msw.c, WM_KEYDOWN handling.)
|
|
1883
|
|
1884 NOTE: These functions are also used at startup. */
|
771
|
1885
|
|
1886 Extbyte *
|
|
1887 convert_multibyte_to_unicode_malloc (const Extbyte *src, Bytecount n,
|
|
1888 int cp, Bytecount *size_out)
|
|
1889 {
|
2367
|
1890 Charcount nout = MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, 0, 0);
|
771
|
1891 Extbyte *outp = xnew_array (Extbyte, nout * sizeof (WCHAR));
|
|
1892
|
2367
|
1893 MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, (LPWSTR) outp, nout);
|
771
|
1894 if (size_out)
|
|
1895 *size_out = nout * sizeof (WCHAR);
|
|
1896 return outp;
|
|
1897 }
|
|
1898
|
2367
|
1899 Extbyte *
|
|
1900 convert_unicode_to_multibyte_malloc (const Extbyte *src, Bytecount n,
|
|
1901 int cp, Bytecount *size_out)
|
|
1902 {
|
|
1903 Bytecount nout = WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src,
|
|
1904 n / sizeof (WCHAR),
|
|
1905 0, 0, WCTOMB_INVALID_STRING, 0);
|
|
1906 Extbyte *outp = xnew_array (Extbyte, nout);
|
|
1907
|
|
1908 WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src,
|
|
1909 n / sizeof (WCHAR), (LPSTR) outp, nout,
|
|
1910 WCTOMB_INVALID_STRING, 0);
|
|
1911 if (size_out)
|
|
1912 *size_out = nout;
|
|
1913 return outp;
|
|
1914 }
|
|
1915
|
771
|
1916 /* Convert MS Windows multibyte to internal, with specified code page.
|
|
1917 See above for why this exists, and the TO_INTERNAL_FORMAT() macros
|
|
1918 aren't just used. */
|
|
1919
|
867
|
1920 Ibyte *
|
771
|
1921 convert_multibyte_to_internal_malloc (const Extbyte *src, Bytecount n,
|
|
1922 int cp, Bytecount *size_out)
|
|
1923 {
|
|
1924 Bytecount size;
|
|
1925 Extbyte *unidata = convert_multibyte_to_unicode_malloc (src, n, cp, &size);
|
867
|
1926 Ibyte *intdata;
|
771
|
1927
|
|
1928 TO_INTERNAL_FORMAT (DATA, (unidata, size), MALLOC, (intdata, size),
|
|
1929 Qmswindows_unicode);
|
|
1930
|
1726
|
1931 xfree (unidata, Extbyte *);
|
771
|
1932
|
|
1933 if (size_out)
|
|
1934 *size_out = size;
|
|
1935
|
|
1936 return intdata;
|
|
1937 }
|
|
1938
|
2367
|
1939 static void
|
|
1940 unicode_multibyte_convert_now_damn_it (const void *src, Bytecount src_size,
|
|
1941 int to_unicode, void **dst,
|
|
1942 Bytecount *dst_size, int cp)
|
|
1943 {
|
|
1944 if (to_unicode)
|
|
1945 {
|
|
1946 Charcount nout = MultiByteToWideChar (cp, MBTOWC_OPTIONS, (LPSTR) src,
|
|
1947 src_size, 0, 0);
|
|
1948 Extbyte *outp = (Extbyte *) stack_like_malloc (nout * sizeof (WCHAR));
|
|
1949
|
|
1950 MultiByteToWideChar (cp, MBTOWC_OPTIONS, (LPSTR) src, src_size,
|
|
1951 (LPWSTR) outp, nout);
|
|
1952 *dst = (void *) outp;
|
|
1953 *dst_size = nout * sizeof (WCHAR);
|
|
1954 }
|
|
1955 else
|
|
1956 {
|
|
1957 Bytecount nout = WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src,
|
|
1958 src_size / sizeof (WCHAR),
|
|
1959 0, 0, WCTOMB_INVALID_STRING, 0);
|
|
1960 Extbyte *outp = (Extbyte *) stack_like_malloc (nout);
|
|
1961
|
|
1962 WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src,
|
|
1963 src_size / sizeof (WCHAR), (LPSTR) outp, nout,
|
|
1964 WCTOMB_INVALID_STRING, 0);
|
|
1965 *dst = (void *) outp;
|
|
1966 *dst_size = nout;
|
|
1967 }
|
|
1968 }
|
|
1969
|
|
1970 Bytecount
|
|
1971 unicode_multibyte_convert_size (const char *srctext, const void *src,
|
|
1972 Bytecount src_size, int to_unicode, int cp)
|
|
1973 {
|
|
1974 alloca_convert_vals vals;
|
|
1975
|
|
1976 assert (find_pos_of_existing_active_alloca_convert (srctext) < 0);
|
|
1977
|
|
1978 vals.srctext = srctext;
|
|
1979
|
|
1980 unicode_multibyte_convert_now_damn_it (src, src_size, to_unicode, &vals.dst,
|
|
1981 &vals.dst_size, cp);
|
|
1982
|
|
1983 Dynarr_add (active_alloca_convert, vals);
|
|
1984 return vals.dst_size;
|
|
1985 }
|
|
1986
|
|
1987 void *
|
|
1988 unicode_multibyte_convert_copy_data (const char *srctext, void *alloca_data)
|
|
1989 {
|
|
1990 alloca_convert_vals *vals;
|
|
1991 int i = find_pos_of_existing_active_alloca_convert (srctext);
|
|
1992
|
|
1993 assert (i >= 0);
|
|
1994 vals = Dynarr_atp (active_alloca_convert, i);
|
|
1995 assert (alloca_data);
|
|
1996 memcpy (alloca_data, vals->dst, vals->dst_size);
|
|
1997 stack_like_free (vals->dst);
|
|
1998 Dynarr_delete (active_alloca_convert, i);
|
|
1999 return alloca_data;
|
|
2000 }
|
|
2001
|
771
|
2002 /* Convert multibyte to Unicode according to the specified code page
|
|
2003 and append the results onto the specified Dynarr. See above. */
|
|
2004
|
|
2005 void
|
|
2006 convert_multibyte_to_unicode_dynarr (const Extbyte *src, Bytecount n,
|
|
2007 int cp, unsigned_char_dynarr *dst)
|
|
2008 {
|
2367
|
2009 Charcount nout = MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, 0, 0);
|
771
|
2010 void *outp;
|
|
2011
|
|
2012 Dynarr_add_many (dst, 0, nout * sizeof (WCHAR));
|
|
2013 /* dynarr's buffer may be realloc()ed by call above, so access it after */
|
|
2014 outp = Dynarr_atp (dst, Dynarr_length (dst) - nout * sizeof (WCHAR));
|
2367
|
2015 MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, (LPWSTR) outp, nout);
|
771
|
2016 }
|
|
2017
|
2367
|
2018 void
|
|
2019 convert_unicode_to_multibyte_dynarr (const Extbyte *src, Bytecount n,
|
|
2020 int cp, unsigned_char_dynarr *dst)
|
|
2021 {
|
|
2022 Bytecount nout = WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src,
|
|
2023 n / sizeof (WCHAR),
|
|
2024 0, 0, WCTOMB_INVALID_STRING, 0);
|
|
2025 void *outp;
|
|
2026
|
|
2027 Dynarr_add_many (dst, 0, nout);
|
|
2028 /* dynarr's buffer may be realloc()ed by call above, so access it after */
|
|
2029 outp = Dynarr_atp (dst, Dynarr_length (dst) - nout);
|
|
2030 WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src,
|
|
2031 n / sizeof (WCHAR), (LPSTR) outp, nout,
|
|
2032 WCTOMB_INVALID_STRING, 0);
|
|
2033 }
|
|
2034
|
|
2035
|
771
|
2036 /* Convert MS Windows multibyte to Unicode. */
|
|
2037
|
|
2038 static Bytecount
|
|
2039 mswindows_multibyte_to_unicode_convert (struct coding_stream *str,
|
|
2040 const unsigned char *src,
|
|
2041 unsigned_char_dynarr *dst,
|
|
2042 Bytecount n)
|
|
2043 {
|
|
2044 unsigned char *new_src = (unsigned char *) src;
|
|
2045 int i;
|
|
2046 struct mswindows_multibyte_to_unicode_coding_stream *data =
|
|
2047 CODING_STREAM_TYPE_DATA (str, mswindows_multibyte_to_unicode);
|
|
2048 Bytecount orign = n;
|
|
2049
|
|
2050 if (data->cp == 0)
|
|
2051 data->cp = determine_code_page (str->codesys);
|
|
2052 if (data->partial_byte_present)
|
|
2053 {
|
|
2054 new_src = alloca_array (unsigned char, n + 1);
|
|
2055 memcpy (new_src + 1, src, n);
|
|
2056 new_src[0] =
|
|
2057 (unsigned char) data->partial_byte;
|
|
2058 n++;
|
|
2059 }
|
|
2060
|
|
2061 if (str->direction == CODING_DECODE)
|
|
2062 {
|
|
2063 for (i = n - 1; i >= 0; i--)
|
|
2064 {
|
|
2065 if (!IsDBCSLeadByteEx (data->cp, new_src[i]))
|
|
2066 break;
|
|
2067 }
|
|
2068
|
|
2069 i++;
|
|
2070
|
|
2071 for (; i < n; i++)
|
|
2072 {
|
|
2073 if (IsDBCSLeadByteEx (data->cp, new_src[i]))
|
|
2074 i++;
|
|
2075 }
|
|
2076
|
|
2077 if (i > n)
|
|
2078 {
|
|
2079 /* a char is split across the boundary */
|
|
2080 data->partial_byte = new_src[n - 1];
|
|
2081 data->partial_byte_present = 1;
|
|
2082 n--;
|
|
2083 }
|
|
2084 else
|
|
2085 data->partial_byte_present = 0;
|
|
2086
|
|
2087 convert_multibyte_to_unicode_dynarr ((Extbyte *) new_src, n, data->cp,
|
|
2088 dst);
|
|
2089 }
|
|
2090 else
|
|
2091 {
|
|
2092 if (n & 1)
|
|
2093 {
|
|
2094 /* a char is split across the boundary */
|
|
2095 data->partial_byte = new_src[n - 1];
|
|
2096 data->partial_byte_present = 1;
|
|
2097 n--;
|
|
2098 }
|
|
2099 else
|
|
2100 data->partial_byte_present = 0;
|
|
2101
|
2367
|
2102 convert_unicode_to_multibyte_dynarr ((Extbyte *) new_src, n, data->cp,
|
|
2103 dst);
|
771
|
2104 }
|
|
2105 return orign;
|
|
2106 }
|
|
2107
|
|
2108 static enum source_sink_type
|
2286
|
2109 mswindows_multibyte_to_unicode_conversion_end_type (Lisp_Object UNUSED (codesys))
|
771
|
2110 {
|
|
2111 return DECODES_BYTE_TO_BYTE;
|
|
2112 }
|
|
2113
|
|
2114
|
|
2115 /************************************************************************/
|
|
2116 /* MS Windows Multibyte methods */
|
|
2117 /************************************************************************/
|
|
2118
|
|
2119 struct mswindows_multibyte_coding_system
|
|
2120 {
|
|
2121 Lisp_Object code_page;
|
|
2122 Lisp_Object locale;
|
|
2123 };
|
|
2124
|
|
2125 struct mswindows_multibyte_coding_stream
|
|
2126 {
|
|
2127 int dummy;
|
|
2128 };
|
|
2129
|
1204
|
2130 static const struct memory_description
|
771
|
2131 mswindows_multibyte_coding_system_description[] = {
|
|
2132 { XD_LISP_OBJECT,
|
1204
|
2133 offsetof (struct mswindows_multibyte_coding_system, code_page) },
|
771
|
2134 { XD_LISP_OBJECT,
|
1204
|
2135 offsetof (struct mswindows_multibyte_coding_system, locale) },
|
771
|
2136 { XD_END }
|
|
2137 };
|
|
2138
|
1204
|
2139 DEFINE_CODING_SYSTEM_TYPE_WITH_DATA (mswindows_multibyte);
|
|
2140
|
771
|
2141 static Bytecount
|
2286
|
2142 mswindows_multibyte_convert (struct coding_stream *UNUSED (str),
|
|
2143 const UExtbyte *UNUSED (src),
|
|
2144 unsigned_char_dynarr *UNUSED (dst), Bytecount n)
|
771
|
2145 {
|
|
2146 Bytecount orign = n;
|
|
2147 /* should never be called; is preprocessed away in the
|
|
2148 canonicalize method */
|
2500
|
2149 ABORT ();
|
771
|
2150 return orign;
|
|
2151 }
|
|
2152
|
|
2153 static void
|
|
2154 mswindows_multibyte_init (Lisp_Object codesys)
|
|
2155 {
|
|
2156 struct mswindows_multibyte_coding_system *data =
|
|
2157 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte);
|
|
2158
|
|
2159 data->code_page = Qnil;
|
|
2160 data->locale = Qnil;
|
|
2161 }
|
|
2162
|
|
2163 static void
|
|
2164 mswindows_multibyte_mark (Lisp_Object codesys)
|
|
2165 {
|
|
2166 struct mswindows_multibyte_coding_system *data =
|
|
2167 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte);
|
|
2168
|
|
2169 mark_object (data->code_page);
|
|
2170 mark_object (data->locale);
|
|
2171 }
|
|
2172
|
|
2173 static int
|
|
2174 mswindows_multibyte_putprop (Lisp_Object codesys,
|
|
2175 Lisp_Object key,
|
|
2176 Lisp_Object value)
|
|
2177 {
|
|
2178 struct mswindows_multibyte_coding_system *data =
|
|
2179 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte);
|
|
2180
|
|
2181 if (EQ (key, Qcode_page))
|
|
2182 data->code_page = value;
|
|
2183 else if (EQ (key, Qlocale))
|
|
2184 data->locale = value;
|
|
2185 else
|
|
2186 return 0;
|
|
2187 return 1;
|
|
2188 }
|
|
2189
|
|
2190 static Lisp_Object
|
|
2191 mswindows_multibyte_getprop (Lisp_Object coding_system,
|
|
2192 Lisp_Object prop)
|
|
2193 {
|
|
2194 struct mswindows_multibyte_coding_system *data =
|
|
2195 XCODING_SYSTEM_TYPE_DATA (coding_system, mswindows_multibyte);
|
|
2196
|
|
2197 if (EQ (prop, Qcode_page))
|
|
2198 return data->code_page;
|
|
2199 else if (EQ (prop, Qlocale))
|
|
2200 return data->locale;
|
|
2201 else
|
|
2202 return Qunbound;
|
|
2203 }
|
|
2204
|
|
2205 /* Convert this coding system into the proper chain. */
|
|
2206
|
|
2207 static Lisp_Object
|
|
2208 mswindows_multibyte_canonicalize (Lisp_Object codesys)
|
|
2209 {
|
|
2210 struct mswindows_multibyte_coding_system *data =
|
|
2211 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte);
|
|
2212 Lisp_Object m2u;
|
|
2213
|
|
2214 m2u =
|
|
2215 make_internal_coding_system
|
|
2216 (Qnil,
|
|
2217 "internal-mswindows-multibyte-to-unicode",
|
|
2218 Qmswindows_multibyte_to_unicode,
|
|
2219 Qnil, NILP (data->locale) ?
|
|
2220 list2 (Qcode_page, data->code_page) :
|
|
2221 list4 (Qcode_page, data->code_page, Qlocale, data->locale));
|
|
2222
|
|
2223 return make_internal_coding_system (codesys,
|
|
2224 "internal-mswindows-multibyte-chain",
|
|
2225 Qchain, Qunbound,
|
|
2226 list4 (Qchain,
|
|
2227 list2 (m2u, Qmswindows_unicode),
|
|
2228 Qcanonicalize_after_coding,
|
|
2229 codesys));
|
|
2230 }
|
|
2231
|
|
2232
|
|
2233 void
|
|
2234 syms_of_intl_win32 (void)
|
|
2235 {
|
|
2236 #ifdef MULE
|
|
2237 DEFSUBR (Fmswindows_set_current_locale);
|
|
2238 DEFSUBR (Fmswindows_current_locale);
|
|
2239 DEFSUBR (Fmswindows_user_default_locale);
|
|
2240 DEFSUBR (Fmswindows_system_default_locale);
|
|
2241 DEFSUBR (Fmswindows_locale_code_page);
|
|
2242 DEFSUBR (Fmswindows_locale_oem_code_page);
|
|
2243 DEFSUBR (Fmswindows_supported_locales);
|
|
2244 DEFSUBR (Fmswindows_charset_code_page);
|
|
2245 DEFSUBR (Fmswindows_set_charset_code_page);
|
872
|
2246 DEFSUBR (Fmswindows_charset_registry);
|
|
2247 DEFSUBR (Fmswindows_set_charset_registry);
|
771
|
2248
|
|
2249 #if 0
|
|
2250 DEFSUBR (Fmswindows_get_locale_info);
|
|
2251 DEFSUBR (Fmswindows_get_current_locale_id);
|
|
2252 DEFSUBR (Fmswindows_get_default_locale_id);
|
|
2253 DEFSUBR (Fmswindows_get_valid_locale_ids);
|
|
2254 DEFSUBR (Fmswindows_set_current_locale);
|
|
2255
|
|
2256 DEFSUBR (Fmswindows_get_console_code_page);
|
|
2257 DEFSUBR (Fmswindows_set_console_code_page);
|
|
2258 DEFSUBR (Fmswindows_get_console_output_code_page);
|
|
2259 DEFSUBR (Fmswindows_set_console_output_code_page);
|
|
2260 DEFSUBR (Fmswindows_get_valid_code_pages);
|
|
2261 DEFSUBR (Fmswindows_get_code_page_charset);
|
|
2262
|
|
2263 DEFSUBR (Fmswindows_get_valid_keyboard_layouts);
|
|
2264 DEFSUBR (Fmswindows_get_keyboard_layout);
|
|
2265 DEFSUBR (Fmswindows_set_keyboard_layout);
|
|
2266 #endif
|
|
2267 #endif /* MULE */
|
|
2268
|
|
2269 DEFSYMBOL (Qmswindows_tstr);
|
|
2270 DEFSYMBOL (Qmswindows_multibyte);
|
|
2271 DEFSYMBOL (Qmswindows_multibyte_to_unicode);
|
|
2272 DEFSYMBOL (Qmswindows_unicode);
|
|
2273 DEFSYMBOL (Qmswindows_multibyte_system_default);
|
|
2274
|
|
2275 DEFSYMBOL (Qansi);
|
|
2276 DEFSYMBOL (Qoem);
|
|
2277 DEFSYMBOL (Qmac);
|
|
2278 DEFSYMBOL (Qebcdic);
|
|
2279 }
|
|
2280
|
|
2281 void
|
|
2282 coding_system_type_create_intl_win32 (void)
|
|
2283 {
|
|
2284 INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA
|
|
2285 (mswindows_multibyte_to_unicode,
|
|
2286 "mswindows-multibyte-to-unicode-coding-system-p");
|
|
2287 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, init);
|
|
2288 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, print);
|
|
2289 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, convert);
|
|
2290 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, getprop);
|
|
2291 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, putprop);
|
|
2292 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode,
|
|
2293 conversion_end_type);
|
|
2294
|
|
2295 INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA
|
|
2296 (mswindows_multibyte,
|
|
2297 "mswindows-multibyte-coding-system-p");
|
|
2298 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, convert);
|
|
2299 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, init);
|
|
2300 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, mark);
|
|
2301 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, getprop);
|
|
2302 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, putprop);
|
|
2303 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, canonicalize);
|
|
2304 }
|
|
2305
|
|
2306 void
|
|
2307 reinit_coding_system_type_create_intl_win32 (void)
|
|
2308 {
|
|
2309 REINITIALIZE_CODING_SYSTEM_TYPE (mswindows_multibyte_to_unicode);
|
|
2310 REINITIALIZE_CODING_SYSTEM_TYPE (mswindows_multibyte);
|
|
2311 }
|
|
2312
|
|
2313 void
|
|
2314 vars_of_intl_win32 (void)
|
|
2315 {
|
|
2316 #ifdef MULE
|
|
2317 Vmswindows_charset_code_page_table =
|
|
2318 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
|
|
2319 staticpro (&Vmswindows_charset_code_page_table);
|
872
|
2320 Vmswindows_charset_registry_table =
|
|
2321 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
|
|
2322 staticpro (&Vmswindows_charset_registry_table);
|
771
|
2323 #endif /* MULE */
|
|
2324 }
|
|
2325
|
|
2326 static void
|
|
2327 determine_if_using_unicode (void)
|
|
2328 {
|
|
2329 if (XEUNICODE_P)
|
|
2330 Fdefine_coding_system_alias (Qmswindows_tstr, Qmswindows_unicode);
|
|
2331 else
|
|
2332 Fdefine_coding_system_alias (Qmswindows_tstr,
|
|
2333 Qmswindows_multibyte_system_default);
|
|
2334 }
|
|
2335
|
|
2336 void
|
|
2337 complex_vars_of_intl_win32 (void)
|
|
2338 {
|
|
2339 Fmake_coding_system
|
|
2340 (Qmswindows_unicode, Qunicode,
|
|
2341 build_msg_string ("MS Windows Unicode"),
|
|
2342 nconc2 (list4 (Qdocumentation,
|
|
2343 build_msg_string (
|
|
2344 "Converts to the Unicode encoding for Windows API calls.\n"
|
|
2345 "This encoding is equivalent to standard UTF16, little-endian."
|
|
2346 ),
|
|
2347 Qmnemonic, build_string ("MSW-U")),
|
|
2348 list4 (Qtype, Qutf_16,
|
|
2349 Qlittle_endian, Qt)));
|
|
2350
|
|
2351 #ifdef MULE
|
|
2352 /* Just temporarily. This will get fixed in mule-msw-init.el. */
|
|
2353 Fdefine_coding_system_alias (Qmswindows_multibyte_system_default,
|
|
2354 Qraw_text);
|
|
2355 #else
|
|
2356 /* Not temporarily. These may be referenced by Lisp code so we need to
|
|
2357 define them. */
|
|
2358 Fdefine_coding_system_alias (Qmswindows_multibyte,
|
|
2359 Qraw_text);
|
|
2360 Fdefine_coding_system_alias (Qmswindows_multibyte_system_default,
|
|
2361 Qraw_text);
|
|
2362 Fdefine_coding_system_alias (intern ("mswindows-multibyte-user-default"),
|
|
2363 Qraw_text);
|
|
2364 Fdefine_coding_system_alias (intern ("mswindows-multibyte-oem"),
|
|
2365 Qraw_text);
|
|
2366 Fdefine_coding_system_alias (intern
|
|
2367 ("mswindows-multibyte-oem-system-default"),
|
|
2368 Qraw_text);
|
|
2369 Fdefine_coding_system_alias (intern ("mswindows-multibyte-oem-user-default"),
|
|
2370 Qraw_text);
|
|
2371 #endif /* MULE */
|
|
2372
|
|
2373 determine_if_using_unicode ();
|
|
2374 }
|
|
2375
|
|
2376 void
|
|
2377 init_intl_win32 (void)
|
|
2378 {
|
|
2379 #ifdef MULE
|
|
2380 set_current_lcid (GetUserDefaultLCID ());
|
|
2381 #endif /* MULE */
|
|
2382
|
|
2383 if (initialized)
|
|
2384 /* If not initialized, we also call this, but early -- see the
|
|
2385 previous function. */
|
|
2386 determine_if_using_unicode ();
|
|
2387 }
|