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