Mercurial > hg > xemacs-beta
annotate src/intl-win32.c @ 4792:95b04754ea8c
Make #'equalp more compatible with CL; add a compiler macro, test & doc it.
lisp/ChangeLog addition:
2009-11-08 Aidan Kehoe <kehoea@parhasard.net>
* cl-extra.el (cl-string-vector-equalp)
(cl-bit-vector-vector-equalp, cl-vector-array-equalp)
(cl-hash-table-contents-equalp): New functions, to implement
equalp treating arrays with identical contents as equivalent, as
specified by Common Lisp.
(equalp): Revise this function to implement array equivalence,
and the hash-table equalp behaviour specified by CL.
* cl-macs.el (equalp): Add a compiler macro for this function,
used when one of the arguments is constant, and as such, its type
is known at compile time.
man/ChangeLog addition:
2009-11-08 Aidan Kehoe <kehoea@parhasard.net>
* lispref/objects.texi (Equality Predicates):
Document #'equalp here, as well as #'equal and #'eq.
tests/ChangeLog addition:
2009-12-31 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
Test much of the functionality of equalp; add a pointer to Paul
Dietz' ANSI test suite for this function, converted to Emacs
Lisp. Not including the tests themselves in XEmacs because who
owns the copyright on the files is unclear and the GCL people
didn't respond to my queries.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Thu, 31 Dec 2009 15:09:41 +0000 |
parents | 257b468bf2ca |
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 } |