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