Mercurial > hg > xemacs-beta
annotate src/intl-win32.c @ 4690:257b468bf2ca
Move the #'query-coding-region implementation to C.
This is necessary because there is no reasonable way to access the
corresponding mswindows-multibyte functionality from Lisp, and we need such
functionality if we're going to have a reliable and portable
#'query-coding-region implementation. However, this change doesn't yet
provide #'query-coding-region for the mswindow-multibyte coding systems,
there should be no functional differences between an XEmacs with this change
and one without it.
src/ChangeLog addition:
2009-09-19 Aidan Kehoe <kehoea@parhasard.net>
Move the #'query-coding-region implementation to C.
This is necessary because there is no reasonable way to access the
corresponding mswindows-multibyte functionality from Lisp, and we
need such functionality if we're going to have a reliable and
portable #'query-coding-region implementation. However, this
change doesn't yet provide #'query-coding-region for the
mswindow-multibyte coding systems, there should be no functional
differences between an XEmacs with this change and one without it.
* mule-coding.c (struct fixed_width_coding_system):
Add a new coding system type, fixed_width, and implement it. It
uses the CCL infrastructure but has a much simpler creation API,
and its own query_method, formerly in lisp/mule/mule-coding.el.
* unicode.c:
Move the Unicode query method implementation here from
unicode.el.
* lisp.h: Declare Fmake_coding_system_internal, Fcopy_range_table
here.
* intl-win32.c (complex_vars_of_intl_win32):
Use Fmake_coding_system_internal, not Fmake_coding_system.
* general-slots.h: Add Qsucceeded, Qunencodable, Qinvalid_sequence
here.
* file-coding.h (enum coding_system_variant):
Add fixed_width_coding_system here.
(struct coding_system_methods):
Add query_method and query_lstream_method to the coding system
methods.
Provide flags for the query methods.
Declare the default query method; initialise it correctly in
INITIALIZE_CODING_SYSTEM_TYPE.
* file-coding.c (default_query_method):
New function, the default query method for coding systems that do
not set it. Moved from coding.el.
(make_coding_system_1):
Accept new elements in PROPS in #'make-coding-system; aliases, a
list of aliases; safe-chars and safe-charsets (these were
previously accepted but not saved); and category.
(Fmake_coding_system_internal):
New function, what used to be #'make-coding-system--on Mule
builds, we've now moved some of the functionality of this to
Lisp.
(Fcoding_system_canonical_name_p):
Move this earlier in the file, since it's now called from within
make_coding_system_1.
(Fquery_coding_region):
Move the implementation of this here, from coding.el.
(complex_vars_of_file_coding):
Call Fmake_coding_system_internal, not Fmake_coding_system;
specify safe-charsets properties when we're a mule build.
* extents.h (mouse_highlight_priority, Fset_extent_priority,
Fset_extent_face, Fmap_extents):
Make these available to other C files.
lisp/ChangeLog addition:
2009-09-19 Aidan Kehoe <kehoea@parhasard.net>
Move the #'query-coding-region implementation to C.
* coding.el:
Consolidate code that depends on the presence or absence of Mule
at the end of this file.
(default-query-coding-region, query-coding-region):
Move these functions to C.
(default-query-coding-region-safe-charset-skip-chars-map):
Remove this variable, the corresponding C variable is
Vdefault_query_coding_region_chartab_cache in file-coding.c.
(query-coding-string): Update docstring to reflect actual multiple
values, be more careful about not modifying a range table that
we're currently mapping over.
(encode-coding-char): Make the implementation of this simpler.
(featurep 'mule): Autoload #'make-coding-system from
mule/make-coding-system.el if we're a mule build; provide an
appropriate compiler macro.
Do various non-mule compatibility things if we're not a mule
build.
* update-elc.el (additional-dump-dependencies):
Add mule/make-coding-system as a dump time dependency if we're a
mule build.
* unicode.el (ccl-encode-to-ucs-2):
(decode-char):
(encode-char):
Move these earlier in the file, for the sake of some byte compile
warnings.
(unicode-query-coding-region):
Move this to unicode.c
* mule/make-coding-system.el:
New file, not dumped. Contains the functionality to rework the
arguments necessary for fixed-width coding systems, and contains
the implementation of #'make-coding-system, which now calls
#'make-coding-system-internal.
* mule/vietnamese.el (viscii):
* mule/latin.el (iso-8859-2):
(windows-1250):
(iso-8859-3):
(iso-8859-4):
(iso-8859-14):
(iso-8859-15):
(iso-8859-16):
(iso-8859-9):
(macintosh):
(windows-1252):
* mule/hebrew.el (iso-8859-8):
* mule/greek.el (iso-8859-7):
(windows-1253):
* mule/cyrillic.el (iso-8859-5):
(koi8-r):
(koi8-u):
(windows-1251):
(alternativnyj):
(koi8-ru):
(koi8-t):
(koi8-c):
(koi8-o):
* mule/arabic.el (iso-8859-6):
(windows-1256):
Move all these coding systems to being of type fixed-width, not of
type CCL. This allows the distinct query-coding-region for them to
be in C, something which will eventually allow us to implement
query-coding-region for the mswindows-multibyte coding systems.
* mule/general-late.el (posix-charset-to-coding-system-hash):
Document why we're pre-emptively persuading the byte compiler that
the ELC for this file needs to be written using escape-quoted.
Call #'set-unicode-query-skip-chars-args, now the Unicode
query-coding-region implementation is in C.
* mule/thai-xtis.el (tis-620):
Don't bother checking whether we're XEmacs or not here.
* mule/mule-coding.el:
Move the eight bit fixed-width functionality from this file to
make-coding-system.el.
tests/ChangeLog addition:
2009-09-19 Aidan Kehoe <kehoea@parhasard.net>
* automated/mule-tests.el:
Check a coding system's type, not an 8-bit-fixed property, for
whether that coding system should be treated as a fixed-width
coding system.
* automated/query-coding-tests.el:
Don't test the query coding functionality for mswindows-multibyte
coding systems, it's not yet implemented.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 19 Sep 2009 22:53:13 +0100 |
parents | 6b2ef948e140 |
children | b3ea9c582280 |
rev | line source |
---|---|
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 | |
3767 | 786 \(some may not be recognized if the compiler is older than VC++ 6.0) |
771 | 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 | |
3767 | 861 \(some may not be recognized if the compiler is older than VC++ 6.0) |
771 | 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 | |
2935 | 1553 LCID |
1554 mswindows_current_locale (void) | |
1555 { | |
1556 /* In non-MULE version just return the default locale */ | |
1557 return GetUserDefaultLCID (); | |
1558 } | |
1559 | |
771 | 1560 #endif /* MULE */ |
1561 | |
1562 | |
1563 #ifdef CYGWIN | |
1564 | |
1111 | 1565 /* based on newlib str*() */ |
1566 | |
1567 #ifndef HAVE_WCSCMP | |
1568 | |
1569 int | |
1570 wcscmp (const wchar_t *s1, const wchar_t *s2) | |
1571 { | |
3648 | 1572 if (s1 == NULL || s2 == NULL) return NULL; |
1111 | 1573 while (*s1 != '\0' && *s1 == *s2) |
1574 { | |
1575 s1++; | |
1576 s2++; | |
1577 } | |
1578 | |
1579 return *s1 - *s2; | |
1580 } | |
1581 | |
1582 #endif /* not HAVE_WCSCMP */ | |
1583 | |
1584 #ifndef HAVE_WCSLEN | |
1585 | |
1586 size_t | |
1587 wcslen (const wchar_t *str) | |
1588 { | |
3648 | 1589 if (str == NULL) return NULL; |
1111 | 1590 const wchar_t *start = str; |
1591 | |
1592 while (*str) | |
1593 str++; | |
1594 | |
1595 return str - start; | |
1596 } | |
1597 | |
1598 #endif /* not HAVE_WCSLEN */ | |
771 | 1599 |
1600 wchar_t * | |
1601 wcsncpy (wchar_t *dst0, const wchar_t *src0, size_t count) | |
1602 { | |
3648 | 1603 if (dst0 == NULL || src0 == NULL) return NULL; |
771 | 1604 wchar_t *dscan; |
1605 const wchar_t *sscan; | |
1606 | |
1607 dscan = dst0; | |
1608 sscan = src0; | |
1609 while (count > 0) | |
1610 { | |
1611 --count; | |
1612 if ((*dscan++ = *sscan++) == '\0') | |
1613 break; | |
1614 } | |
1615 while (count-- > 0) | |
1616 *dscan++ = '\0'; | |
1617 | |
1618 return dst0; | |
1619 } | |
1620 | |
1621 wchar_t * | |
1622 wcscpy (wchar_t *dst0, const wchar_t *src0) | |
1623 { | |
3648 | 1624 if (dst0 == NULL || src0 == NULL) return NULL; |
771 | 1625 wchar_t *s = dst0; |
1626 | |
1627 while ((*dst0++ = *src0++)) | |
1628 ; | |
1629 | |
1630 return s; | |
1631 } | |
1632 | |
1633 wchar_t * | |
1634 wcsdup (const wchar_t *str) | |
1635 { | |
3648 | 1636 if (str == NULL) return NULL; |
771 | 1637 int len = wcslen (str) + 1; |
2367 | 1638 wchar_t *val = xnew_array (wchar_t, len); |
771 | 1639 |
1640 if (val == 0) return 0; | |
1641 return (wchar_t *) memcpy (val, str, len * sizeof (wchar_t)); | |
1642 } | |
1643 | |
1644 #endif /* CYGWIN */ | |
1645 | |
1646 | |
1647 /************************************************************************/ | |
1648 /* MS Windows multibyte-to-unicode methods */ | |
1649 /************************************************************************/ | |
1650 | |
1651 enum mswindows_multibyte_cp_type | |
1652 { | |
1653 MULTIBYTE_ANSI, | |
1654 MULTIBYTE_OEM, | |
1655 MULTIBYTE_EBCDIC, | |
1656 MULTIBYTE_MAC | |
1657 }; | |
1658 | |
1659 enum mswindows_multibyte_locale_type | |
1660 { | |
1661 MULTIBYTE_SPECIFIED_LOCALE, | |
1662 MULTIBYTE_SPECIFIED_CODE_PAGE, | |
1663 MULTIBYTE_CURRENT, | |
1664 MULTIBYTE_USER_DEFAULT, | |
1665 MULTIBYTE_SYSTEM_DEFAULT | |
1666 }; | |
1667 | |
1668 struct mswindows_multibyte_to_unicode_coding_system | |
1669 { | |
1670 enum mswindows_multibyte_cp_type cp_type; | |
1671 enum mswindows_multibyte_locale_type locale_type; | |
1672 LCID locale; /* if locale_type is MULTIBYTE_SPECIFIED_LOCALE */ | |
1673 int cp; /* if locale_type is MULTIBYTE_SPECIFIED_CODE_PAGE */ | |
1674 }; | |
1675 | |
1676 struct mswindows_multibyte_to_unicode_coding_stream | |
1677 { | |
1678 int partial_byte; | |
1679 int partial_byte_present; | |
1680 int cp; | |
1681 }; | |
1682 | |
1204 | 1683 static const struct memory_description |
771 | 1684 mswindows_multibyte_to_unicode_coding_system_description[] = { |
1685 { XD_END } | |
1686 }; | |
1687 | |
1204 | 1688 DEFINE_CODING_SYSTEM_TYPE_WITH_DATA (mswindows_multibyte_to_unicode); |
1689 | |
771 | 1690 static void |
1691 mswindows_multibyte_to_unicode_init (Lisp_Object codesys) | |
1692 { | |
1693 struct mswindows_multibyte_to_unicode_coding_system *data = | |
1694 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte_to_unicode); | |
1695 | |
1696 data->cp_type = MULTIBYTE_ANSI; | |
1697 data->locale_type = MULTIBYTE_CURRENT; | |
1698 } | |
1699 | |
1700 static Lisp_Object | |
2286 | 1701 lcid_to_locale_mule_or_no (LCID USED_IF_MULE (lcid)) |
771 | 1702 { |
1703 #ifdef MULE | |
1704 return lcid_to_locale (lcid); | |
1705 #else | |
1706 return Fcons (build_string ("NEUTRAL"), build_string ("DEFAULT")); | |
1707 #endif | |
1708 } | |
1709 | |
1710 static int | |
2286 | 1711 determine_code_page (Lisp_Object USED_IF_MULE (codesys)) |
771 | 1712 { |
1713 #ifdef MULE | |
1714 LCID locale; | |
1715 struct mswindows_multibyte_to_unicode_coding_system *data = | |
1716 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte_to_unicode); | |
1717 | |
1718 switch (data->locale_type) | |
1719 { | |
1720 case MULTIBYTE_SPECIFIED_CODE_PAGE: | |
1721 return data->cp; | |
1722 case MULTIBYTE_SPECIFIED_LOCALE: | |
1723 locale = data->locale; break; | |
1724 case MULTIBYTE_CURRENT: | |
1725 locale = mswindows_current_locale (); break; | |
1726 case MULTIBYTE_USER_DEFAULT: | |
1727 locale = GetUserDefaultLCID (); break; | |
1728 case MULTIBYTE_SYSTEM_DEFAULT: | |
1729 locale = GetSystemDefaultLCID (); break; | |
1730 default: | |
2500 | 1731 ABORT (); locale = 0; |
771 | 1732 } |
1733 | |
1734 switch (data->cp_type) | |
1735 { | |
1736 case MULTIBYTE_ANSI: | |
1737 return mswindows_locale_to_code_page (locale); | |
1738 case MULTIBYTE_OEM: | |
1739 return mswindows_locale_to_oem_code_page (locale); | |
1740 case MULTIBYTE_EBCDIC: | |
1741 #ifdef LOCALE_IDEFAULTEBCDICCODEPAGE /* Doesn't exist under Cygwin */ | |
1742 { | |
1743 char codepagestr[10]; | |
1744 GetLocaleInfoA (locale, LOCALE_IDEFAULTEBCDICCODEPAGE, codepagestr, | |
1745 10); | |
1746 return atoi (codepagestr); | |
1747 } | |
1748 #else | |
1749 invalid_operation ("Unable to determine EBCDIC code page for locale", | |
1750 lcid_to_locale (locale)); | |
1751 return 0; | |
1752 #endif | |
1753 case MULTIBYTE_MAC: | |
1754 #ifdef LOCALE_IDEFAULTMACCODEPAGE /* Doesn't exist under Cygwin */ | |
1755 { | |
1756 char codepagestr[10]; | |
1757 GetLocaleInfoA (locale, LOCALE_IDEFAULTMACCODEPAGE, codepagestr, | |
1758 10); | |
1759 return atoi (codepagestr); | |
1760 } | |
1761 #else | |
1762 invalid_operation ("Unable to determine Mac code page for locale", | |
1763 lcid_to_locale (locale)); | |
1764 return 0; | |
1765 #endif | |
1766 default: | |
2500 | 1767 ABORT (); return 0; |
771 | 1768 } |
1769 #else /* not MULE */ | |
1770 return CP_ACP; | |
1771 #endif | |
1772 } | |
1773 | |
1774 static int | |
1775 mswindows_multibyte_to_unicode_putprop (Lisp_Object codesys, | |
1776 Lisp_Object key, | |
1777 Lisp_Object value) | |
1778 { | |
1779 struct mswindows_multibyte_to_unicode_coding_system *data = | |
1780 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte_to_unicode); | |
1781 | |
1782 if (EQ (key, Qcode_page)) | |
1783 { | |
1784 if (EQ (value, Qansi)) | |
1785 data->cp_type = MULTIBYTE_ANSI; | |
1786 else if (EQ (value, Qoem)) | |
1787 data->cp_type = MULTIBYTE_OEM; | |
1788 else if (EQ (value, Qebcdic)) | |
1789 data->cp_type = MULTIBYTE_EBCDIC; | |
1790 else if (EQ (value, Qmac)) | |
1791 data->cp_type = MULTIBYTE_MAC; | |
1792 else | |
1793 { | |
1794 CHECK_NATNUM (value); | |
1795 data->locale_type = MULTIBYTE_SPECIFIED_CODE_PAGE; | |
1796 data->cp = XINT (value); | |
1797 } | |
1798 } | |
1799 else if (EQ (key, Qlocale)) | |
1800 { | |
1801 if (EQ (value, Qcurrent)) | |
1802 data->locale_type = MULTIBYTE_CURRENT; | |
1803 else if (EQ (value, Quser_default)) | |
1804 data->locale_type = MULTIBYTE_USER_DEFAULT; | |
1805 else if (EQ (value, Qsystem_default)) | |
1806 data->locale_type = MULTIBYTE_SYSTEM_DEFAULT; | |
1807 else | |
1808 { | |
1809 data->locale_type = MULTIBYTE_SPECIFIED_LOCALE; | |
1810 #ifdef MULE | |
1811 data->locale = locale_to_lcid (value); | |
1812 #else | |
1813 data->locale = 0; | |
1814 #endif | |
1815 } | |
1816 } | |
1817 else | |
1818 return 0; | |
1819 return 1; | |
1820 } | |
1821 | |
1822 static Lisp_Object | |
1823 mswindows_multibyte_to_unicode_getprop (Lisp_Object coding_system, | |
1824 Lisp_Object prop) | |
1825 { | |
1826 struct mswindows_multibyte_to_unicode_coding_system *data = | |
1827 XCODING_SYSTEM_TYPE_DATA (coding_system, mswindows_multibyte_to_unicode); | |
1828 | |
1829 if (EQ (prop, Qcode_page)) | |
1830 { | |
1831 if (data->locale_type == MULTIBYTE_SPECIFIED_CODE_PAGE) | |
1832 return make_int (data->cp); | |
1833 else | |
1834 switch (data->cp_type) | |
1835 { | |
1836 case MULTIBYTE_ANSI: return Qansi; | |
1837 case MULTIBYTE_OEM: return Qoem; | |
1838 case MULTIBYTE_EBCDIC: return Qebcdic; | |
1839 case MULTIBYTE_MAC: return Qmac; | |
2500 | 1840 default: ABORT (); |
771 | 1841 } |
1842 } | |
1843 else if (EQ (prop, Qlocale)) | |
1844 { | |
1845 switch (data->locale_type) | |
1846 { | |
1847 case MULTIBYTE_CURRENT: return Qcurrent; | |
1848 case MULTIBYTE_USER_DEFAULT: return Quser_default; | |
1849 case MULTIBYTE_SYSTEM_DEFAULT: return Qsystem_default; | |
1850 case MULTIBYTE_SPECIFIED_LOCALE: | |
1851 return lcid_to_locale_mule_or_no (data->locale); | |
1852 | |
1853 case MULTIBYTE_SPECIFIED_CODE_PAGE: | |
1854 return Qnil; | |
2500 | 1855 default: ABORT (); |
771 | 1856 } |
1857 } | |
1858 | |
1859 return Qunbound; | |
1860 } | |
1861 | |
1862 static void | |
2286 | 1863 mswindows_multibyte_to_unicode_print (Lisp_Object cs, Lisp_Object printcharfun, |
1864 int UNUSED (escapeflag)) | |
771 | 1865 { |
1866 struct mswindows_multibyte_to_unicode_coding_system *data = | |
1867 XCODING_SYSTEM_TYPE_DATA (cs, mswindows_multibyte_to_unicode); | |
1868 | |
826 | 1869 write_c_string (printcharfun, "("); |
771 | 1870 if (data->locale_type == MULTIBYTE_SPECIFIED_CODE_PAGE) |
1871 print_internal (make_int (data->cp), printcharfun, 1); | |
1872 else | |
1873 { | |
800 | 1874 write_fmt_string_lisp (printcharfun, "%s, ", 1, mswindows_multibyte_to_unicode_getprop (cs, Qlocale)); |
1875 print_internal (mswindows_multibyte_to_unicode_getprop (cs, Qcode_page), printcharfun, 0); | |
771 | 1876 } |
826 | 1877 write_c_string (printcharfun, ")"); |
771 | 1878 } |
1879 | |
2367 | 1880 /* ----------------------------------------------------------------------- */ |
1881 /* Unicode/Multibyte converters */ | |
1882 /* ----------------------------------------------------------------------- */ | |
1883 | |
771 | 1884 /* Convert multibyte to Unicode according to the specified code page |
1885 and return the value as a malloc()ed string. This currently exists | |
1886 because the TO_INTERNAL_FORMAT() mechanism -- the normal way to do | |
1887 such conversions -- has no way of passing in a parameter to control | |
1888 the operation. We could use a global variable to pass this value | |
1889 in, but that runs the risk of causing problems due to reentrancy. | |
1890 (You might say, yeah, right, how can TO_INTERNAL_FORMAT() get | |
1891 called recursively merely when I'm doing a simple conversion | |
1892 operation? It turns out this can and does happen, consistently, as | |
1893 a result of calling QUIT -- it happens consistently for complicated | |
2367 | 1894 reasons outlined in event-msw.c, WM_KEYDOWN handling.) |
1895 | |
1896 NOTE: These functions are also used at startup. */ | |
771 | 1897 |
1898 Extbyte * | |
1899 convert_multibyte_to_unicode_malloc (const Extbyte *src, Bytecount n, | |
1900 int cp, Bytecount *size_out) | |
1901 { | |
2367 | 1902 Charcount nout = MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, 0, 0); |
771 | 1903 Extbyte *outp = xnew_array (Extbyte, nout * sizeof (WCHAR)); |
1904 | |
2367 | 1905 MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, (LPWSTR) outp, nout); |
771 | 1906 if (size_out) |
1907 *size_out = nout * sizeof (WCHAR); | |
1908 return outp; | |
1909 } | |
1910 | |
2367 | 1911 Extbyte * |
1912 convert_unicode_to_multibyte_malloc (const Extbyte *src, Bytecount n, | |
1913 int cp, Bytecount *size_out) | |
1914 { | |
1915 Bytecount nout = WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src, | |
1916 n / sizeof (WCHAR), | |
1917 0, 0, WCTOMB_INVALID_STRING, 0); | |
1918 Extbyte *outp = xnew_array (Extbyte, nout); | |
1919 | |
1920 WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src, | |
1921 n / sizeof (WCHAR), (LPSTR) outp, nout, | |
1922 WCTOMB_INVALID_STRING, 0); | |
1923 if (size_out) | |
1924 *size_out = nout; | |
1925 return outp; | |
1926 } | |
1927 | |
771 | 1928 /* Convert MS Windows multibyte to internal, with specified code page. |
1929 See above for why this exists, and the TO_INTERNAL_FORMAT() macros | |
1930 aren't just used. */ | |
1931 | |
867 | 1932 Ibyte * |
771 | 1933 convert_multibyte_to_internal_malloc (const Extbyte *src, Bytecount n, |
1934 int cp, Bytecount *size_out) | |
1935 { | |
1936 Bytecount size; | |
1937 Extbyte *unidata = convert_multibyte_to_unicode_malloc (src, n, cp, &size); | |
867 | 1938 Ibyte *intdata; |
771 | 1939 |
1940 TO_INTERNAL_FORMAT (DATA, (unidata, size), MALLOC, (intdata, size), | |
1941 Qmswindows_unicode); | |
1942 | |
1726 | 1943 xfree (unidata, Extbyte *); |
771 | 1944 |
1945 if (size_out) | |
1946 *size_out = size; | |
1947 | |
1948 return intdata; | |
1949 } | |
1950 | |
2367 | 1951 static void |
1952 unicode_multibyte_convert_now_damn_it (const void *src, Bytecount src_size, | |
1953 int to_unicode, void **dst, | |
1954 Bytecount *dst_size, int cp) | |
1955 { | |
1956 if (to_unicode) | |
1957 { | |
1958 Charcount nout = MultiByteToWideChar (cp, MBTOWC_OPTIONS, (LPSTR) src, | |
1959 src_size, 0, 0); | |
1960 Extbyte *outp = (Extbyte *) stack_like_malloc (nout * sizeof (WCHAR)); | |
1961 | |
1962 MultiByteToWideChar (cp, MBTOWC_OPTIONS, (LPSTR) src, src_size, | |
1963 (LPWSTR) outp, nout); | |
1964 *dst = (void *) outp; | |
1965 *dst_size = nout * sizeof (WCHAR); | |
1966 } | |
1967 else | |
1968 { | |
1969 Bytecount nout = WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src, | |
1970 src_size / sizeof (WCHAR), | |
1971 0, 0, WCTOMB_INVALID_STRING, 0); | |
1972 Extbyte *outp = (Extbyte *) stack_like_malloc (nout); | |
1973 | |
1974 WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src, | |
1975 src_size / sizeof (WCHAR), (LPSTR) outp, nout, | |
1976 WCTOMB_INVALID_STRING, 0); | |
1977 *dst = (void *) outp; | |
1978 *dst_size = nout; | |
1979 } | |
1980 } | |
1981 | |
1982 Bytecount | |
1983 unicode_multibyte_convert_size (const char *srctext, const void *src, | |
1984 Bytecount src_size, int to_unicode, int cp) | |
1985 { | |
1986 alloca_convert_vals vals; | |
2658 | 1987 |
1988 int pos = find_pos_of_existing_active_alloca_convert (srctext); | |
1989 assert (pos < 0); | |
2367 | 1990 |
1991 vals.srctext = srctext; | |
1992 | |
1993 unicode_multibyte_convert_now_damn_it (src, src_size, to_unicode, &vals.dst, | |
1994 &vals.dst_size, cp); | |
1995 | |
1996 Dynarr_add (active_alloca_convert, vals); | |
1997 return vals.dst_size; | |
1998 } | |
1999 | |
2000 void * | |
2001 unicode_multibyte_convert_copy_data (const char *srctext, void *alloca_data) | |
2002 { | |
2003 alloca_convert_vals *vals; | |
2004 int i = find_pos_of_existing_active_alloca_convert (srctext); | |
2005 | |
2006 assert (i >= 0); | |
2007 vals = Dynarr_atp (active_alloca_convert, i); | |
2008 assert (alloca_data); | |
2009 memcpy (alloca_data, vals->dst, vals->dst_size); | |
2010 stack_like_free (vals->dst); | |
2011 Dynarr_delete (active_alloca_convert, i); | |
2012 return alloca_data; | |
2013 } | |
2014 | |
771 | 2015 /* Convert multibyte to Unicode according to the specified code page |
2016 and append the results onto the specified Dynarr. See above. */ | |
2017 | |
2018 void | |
2019 convert_multibyte_to_unicode_dynarr (const Extbyte *src, Bytecount n, | |
2020 int cp, unsigned_char_dynarr *dst) | |
2021 { | |
2367 | 2022 Charcount nout = MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, 0, 0); |
771 | 2023 void *outp; |
2024 | |
2025 Dynarr_add_many (dst, 0, nout * sizeof (WCHAR)); | |
2026 /* dynarr's buffer may be realloc()ed by call above, so access it after */ | |
2027 outp = Dynarr_atp (dst, Dynarr_length (dst) - nout * sizeof (WCHAR)); | |
2367 | 2028 MultiByteToWideChar (cp, MBTOWC_OPTIONS, src, n, (LPWSTR) outp, nout); |
771 | 2029 } |
2030 | |
2367 | 2031 void |
2032 convert_unicode_to_multibyte_dynarr (const Extbyte *src, Bytecount n, | |
2033 int cp, unsigned_char_dynarr *dst) | |
2034 { | |
2035 Bytecount nout = WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src, | |
2036 n / sizeof (WCHAR), | |
2037 0, 0, WCTOMB_INVALID_STRING, 0); | |
2038 void *outp; | |
2039 | |
2040 Dynarr_add_many (dst, 0, nout); | |
2041 /* dynarr's buffer may be realloc()ed by call above, so access it after */ | |
2042 outp = Dynarr_atp (dst, Dynarr_length (dst) - nout); | |
2043 WideCharToMultiByte (cp, WCTOMB_OPTIONS, (LPWSTR) src, | |
2044 n / sizeof (WCHAR), (LPSTR) outp, nout, | |
2045 WCTOMB_INVALID_STRING, 0); | |
2046 } | |
2047 | |
2048 | |
771 | 2049 /* Convert MS Windows multibyte to Unicode. */ |
2050 | |
2051 static Bytecount | |
2052 mswindows_multibyte_to_unicode_convert (struct coding_stream *str, | |
2053 const unsigned char *src, | |
2054 unsigned_char_dynarr *dst, | |
2055 Bytecount n) | |
2056 { | |
2057 unsigned char *new_src = (unsigned char *) src; | |
2058 int i; | |
2059 struct mswindows_multibyte_to_unicode_coding_stream *data = | |
2060 CODING_STREAM_TYPE_DATA (str, mswindows_multibyte_to_unicode); | |
2061 Bytecount orign = n; | |
2062 | |
2063 if (data->cp == 0) | |
2064 data->cp = determine_code_page (str->codesys); | |
2065 if (data->partial_byte_present) | |
2066 { | |
2067 new_src = alloca_array (unsigned char, n + 1); | |
2068 memcpy (new_src + 1, src, n); | |
2069 new_src[0] = | |
2070 (unsigned char) data->partial_byte; | |
2071 n++; | |
2072 } | |
2073 | |
2074 if (str->direction == CODING_DECODE) | |
2075 { | |
2076 for (i = n - 1; i >= 0; i--) | |
2077 { | |
2078 if (!IsDBCSLeadByteEx (data->cp, new_src[i])) | |
2079 break; | |
2080 } | |
2081 | |
2082 i++; | |
2083 | |
2084 for (; i < n; i++) | |
2085 { | |
2086 if (IsDBCSLeadByteEx (data->cp, new_src[i])) | |
2087 i++; | |
2088 } | |
2089 | |
2090 if (i > n) | |
2091 { | |
2092 /* a char is split across the boundary */ | |
2093 data->partial_byte = new_src[n - 1]; | |
2094 data->partial_byte_present = 1; | |
2095 n--; | |
2096 } | |
2097 else | |
2098 data->partial_byte_present = 0; | |
2099 | |
2100 convert_multibyte_to_unicode_dynarr ((Extbyte *) new_src, n, data->cp, | |
2101 dst); | |
2102 } | |
2103 else | |
2104 { | |
2105 if (n & 1) | |
2106 { | |
2107 /* a char is split across the boundary */ | |
2108 data->partial_byte = new_src[n - 1]; | |
2109 data->partial_byte_present = 1; | |
2110 n--; | |
2111 } | |
2112 else | |
2113 data->partial_byte_present = 0; | |
2114 | |
2367 | 2115 convert_unicode_to_multibyte_dynarr ((Extbyte *) new_src, n, data->cp, |
2116 dst); | |
771 | 2117 } |
2118 return orign; | |
2119 } | |
2120 | |
2121 static enum source_sink_type | |
2286 | 2122 mswindows_multibyte_to_unicode_conversion_end_type (Lisp_Object UNUSED (codesys)) |
771 | 2123 { |
2124 return DECODES_BYTE_TO_BYTE; | |
2125 } | |
2126 | |
2127 | |
2128 /************************************************************************/ | |
2129 /* MS Windows Multibyte methods */ | |
2130 /************************************************************************/ | |
2131 | |
2132 struct mswindows_multibyte_coding_system | |
2133 { | |
2134 Lisp_Object code_page; | |
2135 Lisp_Object locale; | |
2136 }; | |
2137 | |
2138 struct mswindows_multibyte_coding_stream | |
2139 { | |
2140 int dummy; | |
2141 }; | |
2142 | |
1204 | 2143 static const struct memory_description |
771 | 2144 mswindows_multibyte_coding_system_description[] = { |
2145 { XD_LISP_OBJECT, | |
1204 | 2146 offsetof (struct mswindows_multibyte_coding_system, code_page) }, |
771 | 2147 { XD_LISP_OBJECT, |
1204 | 2148 offsetof (struct mswindows_multibyte_coding_system, locale) }, |
771 | 2149 { XD_END } |
2150 }; | |
2151 | |
1204 | 2152 DEFINE_CODING_SYSTEM_TYPE_WITH_DATA (mswindows_multibyte); |
2153 | |
771 | 2154 static Bytecount |
2286 | 2155 mswindows_multibyte_convert (struct coding_stream *UNUSED (str), |
2156 const UExtbyte *UNUSED (src), | |
2157 unsigned_char_dynarr *UNUSED (dst), Bytecount n) | |
771 | 2158 { |
2159 Bytecount orign = n; | |
2160 /* should never be called; is preprocessed away in the | |
2161 canonicalize method */ | |
2500 | 2162 ABORT (); |
771 | 2163 return orign; |
2164 } | |
2165 | |
2166 static void | |
2167 mswindows_multibyte_init (Lisp_Object codesys) | |
2168 { | |
2169 struct mswindows_multibyte_coding_system *data = | |
2170 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte); | |
2171 | |
2172 data->code_page = Qnil; | |
2173 data->locale = Qnil; | |
2174 } | |
2175 | |
2176 static void | |
2177 mswindows_multibyte_mark (Lisp_Object codesys) | |
2178 { | |
2179 struct mswindows_multibyte_coding_system *data = | |
2180 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte); | |
2181 | |
2182 mark_object (data->code_page); | |
2183 mark_object (data->locale); | |
2184 } | |
2185 | |
2186 static int | |
2187 mswindows_multibyte_putprop (Lisp_Object codesys, | |
2188 Lisp_Object key, | |
2189 Lisp_Object value) | |
2190 { | |
2191 struct mswindows_multibyte_coding_system *data = | |
2192 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte); | |
2193 | |
2194 if (EQ (key, Qcode_page)) | |
2195 data->code_page = value; | |
2196 else if (EQ (key, Qlocale)) | |
2197 data->locale = value; | |
2198 else | |
2199 return 0; | |
2200 return 1; | |
2201 } | |
2202 | |
2203 static Lisp_Object | |
2204 mswindows_multibyte_getprop (Lisp_Object coding_system, | |
2205 Lisp_Object prop) | |
2206 { | |
2207 struct mswindows_multibyte_coding_system *data = | |
2208 XCODING_SYSTEM_TYPE_DATA (coding_system, mswindows_multibyte); | |
2209 | |
2210 if (EQ (prop, Qcode_page)) | |
2211 return data->code_page; | |
2212 else if (EQ (prop, Qlocale)) | |
2213 return data->locale; | |
2214 else | |
2215 return Qunbound; | |
2216 } | |
2217 | |
2218 /* Convert this coding system into the proper chain. */ | |
2219 | |
2220 static Lisp_Object | |
2221 mswindows_multibyte_canonicalize (Lisp_Object codesys) | |
2222 { | |
2223 struct mswindows_multibyte_coding_system *data = | |
2224 XCODING_SYSTEM_TYPE_DATA (codesys, mswindows_multibyte); | |
2225 Lisp_Object m2u; | |
2226 | |
2227 m2u = | |
2228 make_internal_coding_system | |
2229 (Qnil, | |
2230 "internal-mswindows-multibyte-to-unicode", | |
2231 Qmswindows_multibyte_to_unicode, | |
2232 Qnil, NILP (data->locale) ? | |
2233 list2 (Qcode_page, data->code_page) : | |
2234 list4 (Qcode_page, data->code_page, Qlocale, data->locale)); | |
2235 | |
2236 return make_internal_coding_system (codesys, | |
2237 "internal-mswindows-multibyte-chain", | |
2238 Qchain, Qunbound, | |
2239 list4 (Qchain, | |
2240 list2 (m2u, Qmswindows_unicode), | |
2241 Qcanonicalize_after_coding, | |
2242 codesys)); | |
2243 } | |
2244 | |
2245 | |
2246 void | |
2247 syms_of_intl_win32 (void) | |
2248 { | |
2249 #ifdef MULE | |
2250 DEFSUBR (Fmswindows_set_current_locale); | |
2251 DEFSUBR (Fmswindows_current_locale); | |
2252 DEFSUBR (Fmswindows_user_default_locale); | |
2253 DEFSUBR (Fmswindows_system_default_locale); | |
2254 DEFSUBR (Fmswindows_locale_code_page); | |
2255 DEFSUBR (Fmswindows_locale_oem_code_page); | |
2256 DEFSUBR (Fmswindows_supported_locales); | |
2257 DEFSUBR (Fmswindows_charset_code_page); | |
2258 DEFSUBR (Fmswindows_set_charset_code_page); | |
872 | 2259 DEFSUBR (Fmswindows_charset_registry); |
2260 DEFSUBR (Fmswindows_set_charset_registry); | |
771 | 2261 |
2262 #if 0 | |
2263 DEFSUBR (Fmswindows_get_locale_info); | |
2264 DEFSUBR (Fmswindows_get_current_locale_id); | |
2265 DEFSUBR (Fmswindows_get_default_locale_id); | |
2266 DEFSUBR (Fmswindows_get_valid_locale_ids); | |
2267 DEFSUBR (Fmswindows_set_current_locale); | |
2268 | |
2269 DEFSUBR (Fmswindows_get_console_code_page); | |
2270 DEFSUBR (Fmswindows_set_console_code_page); | |
2271 DEFSUBR (Fmswindows_get_console_output_code_page); | |
2272 DEFSUBR (Fmswindows_set_console_output_code_page); | |
2273 DEFSUBR (Fmswindows_get_valid_code_pages); | |
2274 DEFSUBR (Fmswindows_get_code_page_charset); | |
2275 | |
2276 DEFSUBR (Fmswindows_get_valid_keyboard_layouts); | |
2277 DEFSUBR (Fmswindows_get_keyboard_layout); | |
2278 DEFSUBR (Fmswindows_set_keyboard_layout); | |
2279 #endif | |
2280 #endif /* MULE */ | |
2281 | |
2282 DEFSYMBOL (Qmswindows_tstr); | |
2283 DEFSYMBOL (Qmswindows_multibyte); | |
2284 DEFSYMBOL (Qmswindows_multibyte_to_unicode); | |
2285 DEFSYMBOL (Qmswindows_unicode); | |
2286 DEFSYMBOL (Qmswindows_multibyte_system_default); | |
2287 | |
2288 DEFSYMBOL (Qansi); | |
2289 DEFSYMBOL (Qoem); | |
2290 DEFSYMBOL (Qmac); | |
2291 DEFSYMBOL (Qebcdic); | |
2292 } | |
2293 | |
2294 void | |
2295 coding_system_type_create_intl_win32 (void) | |
2296 { | |
2297 INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA | |
2298 (mswindows_multibyte_to_unicode, | |
2299 "mswindows-multibyte-to-unicode-coding-system-p"); | |
2300 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, init); | |
2301 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, print); | |
2302 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, convert); | |
2303 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, getprop); | |
2304 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, putprop); | |
2305 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte_to_unicode, | |
2306 conversion_end_type); | |
2307 | |
2308 INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA | |
2309 (mswindows_multibyte, | |
2310 "mswindows-multibyte-coding-system-p"); | |
2311 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, convert); | |
2312 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, init); | |
2313 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, mark); | |
2314 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, getprop); | |
2315 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, putprop); | |
2316 CODING_SYSTEM_HAS_METHOD (mswindows_multibyte, canonicalize); | |
2317 } | |
2318 | |
2319 void | |
2320 reinit_coding_system_type_create_intl_win32 (void) | |
2321 { | |
2322 REINITIALIZE_CODING_SYSTEM_TYPE (mswindows_multibyte_to_unicode); | |
2323 REINITIALIZE_CODING_SYSTEM_TYPE (mswindows_multibyte); | |
2324 } | |
2325 | |
2326 void | |
2327 vars_of_intl_win32 (void) | |
2328 { | |
2329 #ifdef MULE | |
2330 Vmswindows_charset_code_page_table = | |
2331 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | |
2332 staticpro (&Vmswindows_charset_code_page_table); | |
872 | 2333 Vmswindows_charset_registry_table = |
2334 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | |
2335 staticpro (&Vmswindows_charset_registry_table); | |
771 | 2336 #endif /* MULE */ |
2337 } | |
2338 | |
2339 static void | |
2340 determine_if_using_unicode (void) | |
2341 { | |
2342 if (XEUNICODE_P) | |
2343 Fdefine_coding_system_alias (Qmswindows_tstr, Qmswindows_unicode); | |
2344 else | |
2345 Fdefine_coding_system_alias (Qmswindows_tstr, | |
2346 Qmswindows_multibyte_system_default); | |
2347 } | |
2348 | |
2349 void | |
2350 complex_vars_of_intl_win32 (void) | |
2351 { | |
4690
257b468bf2ca
Move the #'query-coding-region implementation to C.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3767
diff
changeset
|
2352 Fmake_coding_system_internal |
771 | 2353 (Qmswindows_unicode, Qunicode, |
2354 build_msg_string ("MS Windows Unicode"), | |
2355 nconc2 (list4 (Qdocumentation, | |
2356 build_msg_string ( | |
2357 "Converts to the Unicode encoding for Windows API calls.\n" | |
2358 "This encoding is equivalent to standard UTF16, little-endian." | |
2359 ), | |
2360 Qmnemonic, build_string ("MSW-U")), | |
3767 | 2361 list4 (Qunicode_type, Qutf_16, |
771 | 2362 Qlittle_endian, Qt))); |
2363 | |
2364 #ifdef MULE | |
2365 /* Just temporarily. This will get fixed in mule-msw-init.el. */ | |
2366 Fdefine_coding_system_alias (Qmswindows_multibyte_system_default, | |
2367 Qraw_text); | |
2368 #else | |
2369 /* Not temporarily. These may be referenced by Lisp code so we need to | |
2370 define them. */ | |
2371 Fdefine_coding_system_alias (Qmswindows_multibyte, | |
2372 Qraw_text); | |
2373 Fdefine_coding_system_alias (Qmswindows_multibyte_system_default, | |
2374 Qraw_text); | |
2375 Fdefine_coding_system_alias (intern ("mswindows-multibyte-user-default"), | |
2376 Qraw_text); | |
2377 Fdefine_coding_system_alias (intern ("mswindows-multibyte-oem"), | |
2378 Qraw_text); | |
2379 Fdefine_coding_system_alias (intern | |
2380 ("mswindows-multibyte-oem-system-default"), | |
2381 Qraw_text); | |
2382 Fdefine_coding_system_alias (intern ("mswindows-multibyte-oem-user-default"), | |
2383 Qraw_text); | |
2384 #endif /* MULE */ | |
2385 | |
2386 determine_if_using_unicode (); | |
2387 } | |
2388 | |
2389 void | |
2390 init_intl_win32 (void) | |
2391 { | |
2392 #ifdef MULE | |
2393 set_current_lcid (GetUserDefaultLCID ()); | |
2394 #endif /* MULE */ | |
2395 | |
2396 if (initialized) | |
2397 /* If not initialized, we also call this, but early -- see the | |
2398 previous function. */ | |
2399 determine_if_using_unicode (); | |
2400 } |