]> code.delx.au - gnu-emacs/blobdiff - lisp/international/mule-cmds.el
Support for ttys with different character locale settings.
[gnu-emacs] / lisp / international / mule-cmds.el
index 338a6025e1811b95e1b83e934b863038e2295b0c..b0340c6079475c24cfff8b8961f3297919530c79 100644 (file)
@@ -27,7 +27,9 @@
 
 ;;; Code:
 
-(eval-when-compile (defvar dos-codepage))
+(eval-when-compile
+  (defvar dos-codepage)
+  (autoload 'widget-value "wid-edit"))
 
 ;;; MULE related key bindings and menus.
 
   t)
 (define-key-after set-coding-system-map [set-terminal-coding-system]
   '(menu-item "For Terminal" set-terminal-coding-system
-             :enable (null (memq window-system '(x w32 mac)))
+             :enable (null (memq initial-window-system '(x w32 mac)))
              :help "How to encode terminal output")
   t)
 (define-key-after set-coding-system-map [separator-3]
@@ -384,6 +386,7 @@ See also `coding-category-list' and `coding-system-category'."
        ;; CODING-SYSTEM is no-conversion or undecided.
        (error "Can't prefer the coding system `%s'" coding-system))
     (set coding-category (or base coding-system))
+    ;; Changing the binding of a coding category requires this call.
     (update-coding-systems-internal)
     (or (eq coding-category (car coding-category-list))
        ;; We must change the order.
@@ -924,7 +927,10 @@ and TO is ignored."
     ;; give when file is re-read.
     ;; But don't do this if we explicitly ignored the cookie
     ;; by using `find-file-literally'.
-    (unless (or (stringp from) find-file-literally)
+    (unless (or (stringp from)
+               find-file-literally
+               (and coding-system
+                    (memq (coding-system-type coding-system) '(0 5))))
       (let ((auto-cs (save-excursion
                       (save-restriction
                         (widen)
@@ -1691,6 +1697,7 @@ The default status is as follows:
      coding-category-ccl
      coding-category-binary))
 
+  ;; Changing the binding of a coding category requires this call.
   (update-coding-systems-internal)
 
   (set-default-coding-systems nil)
@@ -1734,7 +1741,7 @@ The default status is as follows:
 
 (reset-language-environment)
 
-(defun set-display-table-and-terminal-coding-system (language-name)
+(defun set-display-table-and-terminal-coding-system (language-name &optional coding-system display)
   "Set up the display table and terminal coding system for LANGUAGE-NAME."
   (let ((coding (get-language-info language-name 'unibyte-display)))
     (if coding
@@ -1748,7 +1755,7 @@ The default status is as follows:
        (dotimes (i 128)
          (aset standard-display-table (+ i 128) nil))))
     (or (eq window-system 'pc)
-       (set-terminal-coding-system coding))))
+       (set-terminal-coding-system (or coding-system coding) display))))
 
 (defun set-language-environment (language-name)
   "Set up multi-lingual environment for using LANGUAGE-NAME.
@@ -1904,6 +1911,7 @@ of `buffer-file-coding-system' set by this function."
          (while priority
            (set (car categories) (car priority))
            (setq priority (cdr priority) categories (cdr categories)))
+         ;; Changing the binding of a coding category requires this call.
          (update-coding-systems-internal)))))
 
 (defsubst princ-list (&rest args)
@@ -2043,55 +2051,60 @@ of `buffer-file-coding-system' set by this function."
      ;; and Chinese are exceptions, which are listed in the
      ;; non-standard section at the bottom of locale-language-names.
 
-    ; aa Afar
-    ; ab Abkhazian
+    ("aa_DJ" . "Latin-1") ; Afar
+    ("aa" . "UTF-8")
+    ;; ab Abkhazian
     ("af" . "Latin-1") ; Afrikaans
-    ("am" . "Ethiopic") ; Amharic
+    ("am" "Ethiopic" utf-8) ; Amharic
+    ("an" . "Latin-9") ; Aragonese
     ; ar Arabic glibc uses 8859-6
     ; as Assamese
     ; ay Aymara
-    ; az Azerbaijani
+    ("az" . "UTF-8") ; Azerbaijani
     ; ba Bashkir
-    ("be" . "Belarusian") ; Belarusian [Byelorussian until early 1990s]
-    ("bg" . "Bulgarian") ; Bulgarian
+    ("be" "Belarusian" cp1251) ; Belarusian [Byelorussian until early 1990s]
+    ("bg" "Bulgarian" cp1251) ; Bulgarian
     ; bh Bihari
     ; bi Bislama
-    ; bn Bengali, Bangla
+    ("bn" . "UTF-8") ; Bengali, Bangla
     ("bo" . "Tibetan")
     ("br" . "Latin-1") ; Breton
     ("bs" . "Latin-2") ; Bosnian
+    ("byn" . "UTF-8")  ; Bilin; Blin
     ("ca" . "Latin-1") ; Catalan
     ; co Corsican
-    ("cs" . "Czech")
-    ("cy" . "Welsh") ; Welsh [glibc uses Latin-8.  Did this change?]
+    ("cs" "Czech" iso-8859-2)
+    ("cy" "Welsh" iso-8859-14)
     ("da" . "Latin-1") ; Danish
-    ("de" . "German")
+    ("de" "German" iso-8859-1)
     ; dz Bhutani
-    ("el" . "Greek")
+    ("el" "Greek" iso-8859-7)
     ;; Users who specify "en" explicitly typically want Latin-1, not ASCII.
     ;; That's actually what the GNU locales define, modulo things like
     ;; en_IN -- fx.
+    ("en_IN" "English" utf-8) ; glibc uses utf-8 for English in India
     ("en" . "Latin-1") ; English
     ("eo" . "Latin-3") ; Esperanto
-    ("es" . "Spanish")
-    ("et" . "Latin-4") ; Estonian
+    ("es" "Spanish" iso-8859-1)
+    ("et" . "Latin-1") ; Estonian
     ("eu" . "Latin-1") ; Basque
-    ; fa Persian glibc uses utf-8
+    ("fa" . "UTF-8") ; Persian
     ("fi" . "Latin-1") ; Finnish
-    ; fj Fiji
+    ("fj" . "Latin-1") ; Fiji
     ("fo" . "Latin-1") ; Faroese
-    ("fr" . "French") ; French
+    ("fr" "French" iso-8859-1) ; French
     ("fy" . "Latin-1") ; Frisian
     ("ga" . "Latin-1") ; Irish Gaelic (new orthography)
-    ("gd" . "Latin-1") ; Scots Gaelic
-    ("gl" . "Latin-1") ; Galician
+    ("gd" . "Latin-9") ; Scots Gaelic
+    ("gez" "Ethiopic" utf-8) ; Geez
+    ("gl" . "Latin-1") ; Gallegan; Galician
     ; gn Guarani
-    ; gu Gujarati
-    ("gv" . "Latin-8") ; Manx Gaelic  glibc uses 8859-1
+    ("gu" . "UTF-8") ; Gujarati
+    ("gv" . "Latin-1") ; Manx Gaelic
     ; ha Hausa
-    ("he" . "Hebrew")
-    ("hi" . "Devanagari") ; Hindi  glibc uses utf-8
-    ("hr" . "Croatian") ; Croatian
+    ("he" "Hebrew" iso-8859-8)
+    ("hi" "Devanagari" utf-8) ; Hindi
+    ("hr" "Croatian" iso-8859-2) ; Croatian
     ("hu" . "Latin-2") ; Hungarian
     ; hy Armenian
     ; ia Interlingua
@@ -2099,110 +2112,114 @@ of `buffer-file-coding-system' set by this function."
     ; ie Interlingue
     ; ik Inupiak
     ("is" . "Latin-1") ; Icelandic
-    ("it" . "Italian") ; Italian
+    ("it" "Italian" iso-8859-1) ; Italian
     ; iu Inuktitut
-    ("ja" . "Japanese")
+    ("iw" "Hebrew" iso-8859-8)
+    ("ja" "Japanese" euc-jp)
     ; jw Javanese
-    ("ka" . "Georgian") ; Georgian
+    ("ka" "Georgian" georgian-ps) ; Georgian
     ; kk Kazakh
     ("kl" . "Latin-1") ; Greenlandic
     ; km Cambodian
-    ; kn Kannada
-    ("ko" . "Korean")
+    ("kn" "Kannada" utf-8)
+    ("ko" "Korean" euc-kr)
     ; ks Kashmiri
     ; ku Kurdish
     ("kw" . "Latin-1") ; Cornish
     ; ky Kirghiz
     ("la" . "Latin-1") ; Latin
     ("lb" . "Latin-1") ; Luxemburgish
+    ("lg" . "Laint-6") ; Ganda
     ; ln Lingala
-    ("lo" . "Lao") ; Laothian
-    ("lt" . "Lithuanian")
+    ("lo" "Lao" utf-8) ; Laothian
+    ("lt" "Lithuanian" iso-8859-13)
     ("lv" . "Latvian") ; Latvian, Lettish
     ; mg Malagasy
     ("mi" . "Latin-7") ; Maori
-    ("mk" . "Cyrillic-ISO") ; Macedonian
-    ; ml Malayalam
-    ; mn Mongolian
+    ("mk" "Cyrillic-ISO" iso-8859-5) ; Macedonian
+    ("ml" "Malayalam" utf-8)
+    ("mn" . "UTF-8") ; Mongolian
     ; mo Moldavian
-    ("mr" . "Devanagari") ; Marathi  glibc uses utf-8
+    ("mr" "Devanagari" utf-8) ; Marathi
     ("ms" . "Latin-1") ; Malay
     ("mt" . "Latin-3") ; Maltese
     ; my Burmese
     ; na Nauru
-    ("ne" . "Devanagari") ; Nepali
-    ("nl" . "Dutch")
+    ("nb" . "Latin-1") ; Norwegian
+    ("ne" "Devanagari" utf-8) ; Nepali
+    ("nl" "Dutch" iso-8859-1)
     ("no" . "Latin-1") ; Norwegian
     ("oc" . "Latin-1") ; Occitan
-    ; om (Afan) Oromo
+    ("om_ET" . "UTF-8") ; (Afan) Oromo
+    ("om" . "Latin-1") ; (Afan) Oromo
     ; or Oriya
-    ; pa Punjabi
+    ("pa" . "UTF-8") ; Punjabi
     ("pl" . "Latin-2") ; Polish
     ; ps Pashto, Pushto
     ("pt" . "Latin-1") ; Portuguese
     ; qu Quechua
     ("rm" . "Latin-1") ; Rhaeto-Romanic
     ; rn Kirundi
-    ("ro" . "Romanian")
-    ("ru.*[_.]koi8" . "Russian")
-    ("ru" . "Cyrillic-ISO") ; Russian
+    ("ro" "Romanian" iso-8859-2)
+    ("ru_RU" "Russian" iso-8859-5)
+    ("ru_UA" "Russian" koi8-u)
     ; rw Kinyarwanda
     ("sa" . "Devanagari") ; Sanskrit
     ; sd Sindhi
-    ; se   Northern Sami
+    ("se" . "UTF-8") ; Northern Sami
     ; sg Sangho
     ("sh" . "Latin-2") ; Serbo-Croatian
     ; si Sinhalese
-    ("sk" . "Slovak")
-    ("sl" . "Slovenian")
+    ("sid" . "UTF-8") ; Sidamo
+    ("sk" "Slovak" iso-8859-2)
+    ("sl" "Slovenian" iso-8859-2)
     ; sm Samoan
     ; sn Shona
-    ; so Somali
+    ("so_ET" "UTF-8") ; Somali
+    ("so" "Latin-1") ; Somali
     ("sq" . "Latin-1") ; Albanian
+    ("sr_YU@cyrillic" . "Cyrillic-ISO")        ; Serbian (Cyrillic alphabet)
     ("sr" . "Latin-2") ; Serbian (Latin alphabet)
-    ("sr_YU@cyrillic" . "Cyrillic-ISO")        ; per glibc
     ; ss Siswati
-    ; st Sesotho
+    ("st" . "Latin-1") ;  Sesotho
     ; su Sundanese
-    ("sv" . "Swedish") ; Swedish
+    ("sv" "Swedish" iso-8859-1)                ; Swedish
     ("sw" . "Latin-1") ; Swahili
-    ; ta Tamil  glibc uses utf-8
-    ; te Telugu  glibc uses utf-8
-    ("tg" . "Tajik")
-    ("th" . "Thai")
-    ; ti Tigrinya
+    ("ta" "Tamil" utf-8)
+    ("te" . "UTF-8") ; Telugu
+    ("tg" "Tajik" koi8-t)
+    ("th" "Thai" tis-620)
+    ("ti" "Ethiopic" utf-8) ; Tigrinya
+    ("tig_ER" . "UTF-8") ; Tigre
     ; tk Turkmen
     ("tl" . "Latin-1") ; Tagalog
     ; tn Setswana
     ; to Tonga
-    ("tr" . "Turkish")
+    ("tr" "Turkish" iso-8859-9)
     ; ts Tsonga
-    ; tt Tatar
+    ("tt" . "UTF-8") ; Tatar
     ; tw Twi
     ; ug Uighur
-    ("uk" . "Ukrainian") ; Ukrainian
-    ; ur Urdu  glibc uses utf-8
+    ("uk" "Ukrainian" koi8-u)
+    ("ur" . "UTF-8") ; Urdu
+    ("uz_UZ@cyrillic" . "UTF-8"); Uzbek
     ("uz" . "Latin-1") ; Uzbek
-    ("vi" . "Vietnamese") ;  glibc uses utf-8
+    ("vi" "Vietnamese" utf-8)
     ; vo Volapuk
     ("wa" . "Latin-1") ; Walloon
     ; wo Wolof
-    ; xh Xhosa
+    ("xh" . "Latin-1") ; Xhosa
     ("yi" . "Windows-1255") ; Yiddish
     ; yo Yoruba
     ; za Zhuang
-
-    ; glibc:
+    ("zh_HK" . "Chinese-Big5")
+    ("zh_TW" . "Chinese-Big5")
+    ("zh_CN" . "Chinese-GB")
+    ("zh" . "Chinese-GB")
     ; zh_CN.GB18030/GB18030 \
     ; zh_CN.GBK/GBK \
     ; zh_HK/BIG5-HKSCS \
-
-    ("zh.*[._]big5" . "Chinese-BIG5")
-    ("zh.*[._]gbk" . nil) ; Solaris 2.7; has gbk-0 as well as GB 2312.1980-0
-    ("zh_tw" . "Chinese-CNS") ; glibc uses big5
-    ("zh_tw[._]euc-tw" . "Chinese-EUC-TW")
-    ("zh" . "Chinese-GB")
-    ; zu Zulu
+    ("zu" . "Latin-1") ; Zulu
 
     ;; ISO standard locales
     ("c$" . "ASCII")
@@ -2222,10 +2239,16 @@ of `buffer-file-coding-system' set by this function."
     ("chs" . "Chinese-GB") ; MS Windows Chinese Simplified
     ("cht" . "Chinese-BIG5") ; MS Windows Chinese Traditional
     ))
-  "List of pairs of locale regexps and language names.
-The first element whose locale regexp matches the start of a downcased locale
-specifies the language name corresponding to that locale.
-If the language name is nil, there is no corresponding language environment.")
+  "Alist of locale regexps vs the corresponding languages and coding systems.
+Each element has these form:
+  \(LOCALE-REGEXP LANG-ENV CODING-SYSTEM)
+The first element whose LOCALE-REGEXP matches the start of a
+downcased locale specifies the LANG-ENV \(language environtment)
+and CODING-SYSTEM corresponding to that locale.  If there is no
+appropriate language environment, the element may have this form:
+  \(LOCALE-REGEXP . LANG-ENV)
+In this case, LANG-ENV is one of generic language environments for an
+specific encoding such as \"Latin-1\" and \"UTF-8\".")
 
 (defconst locale-charset-language-names
   (purecopy
@@ -2243,20 +2266,43 @@ If the language name is nil, there is no corresponding language environment.")
   "List of pairs of locale regexps and charset language names.
 The first element whose locale regexp matches the start of a downcased locale
 specifies the language name whose charset corresponds to that locale.
-This language name is used if its charsets disagree with the charsets of
-the language name that would otherwise be used for this locale.")
+This language name is used if the locale is not listed in
+`locale-language-names'")
 
 (defconst locale-preferred-coding-systems
   (purecopy
-   '(("ja.*[._]euc" . japanese-iso-8bit)
+   '((".*8859[-_]?1\\>" . iso-8859-1)
+     (".*8859[-_]?2\\>" . iso-8859-2)
+     (".*8859[-_]?3\\>" . iso-8859-3)
+     (".*8859[-_]?4\\>" . iso-8859-4)
+     (".*8859[-_]?9\\>" . iso-8859-9)
+     (".*8859[-_]?14\\>" . iso-8859-14)
+     (".*8859[-_]?15\\>" . iso-8859-15)
+     (".*utf\\(?:-?8\\)?" . utf-8)
+     ;; utf-8@euro exists, so put this after utf-8.  (@euro really
+     ;; specifies the currency, rather than the charset.)
+     (".*@euro" . iso-8859-15)
+     ("koi8-?r" . koi8-r)
+     ("koi8-?u" . koi8-u)
+     ("tcvn" . tcvn)
+     ("big5" . big5)
+     ("euc-?tw" . euc-tw)
+     ;; We don't support GBK, but as it is upper compatible with
+     ;; GB-2312, we setup the default coding system to gb2312.
+     ("gbk" . gb2312)
+     ;; We don't support BIG5-HKSCS, but as it is upper compatible with
+     ;; BIG5, we setup the default coding system to big5.
+     ("big5hkscs" . big5)
+     ("ja.*[._]euc" . japanese-iso-8bit)
      ("ja.*[._]jis7" . iso-2022-jp)
      ("ja.*[._]pck" . japanese-shift-jis)
      ("ja.*[._]sjis" . japanese-shift-jis)
      ("jpn" . japanese-shift-jis)   ; MS-Windows uses this.
-     (".*[._]utf" . utf-8)))
+     ))
   "List of pairs of locale regexps and preferred coding systems.
 The first element whose locale regexp matches the start of a downcased locale
-specifies the coding system to prefer when using that locale.")
+specifies the coding system to prefer when using that locale.
+This coding system is used if the locale specifies a specific charset.")
 
 (defun locale-name-match (key alist)
   "Search for KEY in ALIST, which should be a list of regexp-value pairs.
@@ -2299,120 +2345,11 @@ is returned.  Thus, for instance, if charset \"ISO8859-2\",
            (pop cs)))
        (if c (coding-system-base c)))))
 
-(defun set-locale-translation-file-name ()
-  "Set up the locale-translation-file-name on the current system.
-
-This needs to be done at runtime for the sake of binaries
-possibly transported to a system without X."
-  (setq locale-translation-file-name
-       (let ((files
-              '("/usr/lib/X11/locale/locale.alias" ; e.g. X11R6.4
-                "/usr/X11R6/lib/X11/locale/locale.alias" ; XFree86, e.g. RedHat 4.2
-                "/usr/openwin/lib/locale/locale.alias" ; e.g. Solaris 2.6
-                ;;
-                ;; The following name appears after the X-related names above,
-                ;; since the X-related names are what X actually uses.
-                "/usr/share/locale/locale.alias" ; GNU/Linux sans X
-                )))
-         (while (and files (not (file-exists-p (car files))))
-           (setq files (cdr files)))
-         (car files))))
-
-(defun get-locale-real-name (&optional locale-name)
-  "Return the canonicalized name of locale LOCALE-NAME.
-
-LOCALE-NAME should be a string which is the name of a locale supported
-by the system.  Often it is of the form xx_XX.CODE, where xx is a
-language, XX is a country, and CODE specifies a character set and
-coding system.  For example, the locale name \"ja_JP.EUC\" might name
-a locale for Japanese in Japan using the `japanese-iso-8bit'
-coding-system.  The name may also have a modifier suffix, e.g. `@euro'
-or `@cyrillic'.
-
-If LOCALE-NAME is nil, its value is taken from the environment
-variables LC_ALL, LC_CTYPE and LANG (the first one that is set).
-On server frames, the environment of the emacsclient process is
-used.
-
-See also `set-locale-environment'."
-  (unless locale-name
-    ;; Use the first of these three environment variables
-    ;; that has a nonempty value.
-    (let ((vars '("LC_ALL" "LC_CTYPE" "LANG")))
-      (while (and vars
-                 (= 0 (length locale-name))) ; nil or empty string
-       (setq locale-name (server-getenv (pop vars))))))
-
-    (when locale-name
-      ;; Translate "swedish" into "sv_SE.ISO8859-1", and so on,
-      ;; using the translation file that many systems have.
-      (when locale-translation-file-name
-       (with-temp-buffer
-         (insert-file-contents locale-translation-file-name)
-         (when (re-search-forward
-                (concat "^" (regexp-quote locale-name) ":?[ \t]+") nil t)
-           (setq locale-name (buffer-substring (point) (line-end-position)))))))
-    locale-name)
-
-(defun get-locale-coding-system (&optional locale)
-  "Return the coding system corresponding to locale LOCALE."
-  (setq locale (or locale (get-locale-real-name nil)))
-  (when locale
-    (or (locale-name-match locale locale-preferred-coding-systems)
-       (when locale
-         (if (string-match "\\.\\([^@]+\\)" locale)
-             (locale-charset-to-coding-system
-              (match-string 1 locale)))))))
-
-(defun configure-display-for-locale (&optional locale)
-  "Set up terminal for locale LOCALE.
-
-The display table, the terminal coding system and the keyboard
-coding system of the current display device are set up for the
-given locale."
-  (setq locale (or locale (get-locale-real-name nil)))
-
-  (when locale
-    (let ((language-name
-          (locale-name-match locale locale-language-names))
-         (charset-language-name
-          (locale-name-match locale locale-charset-language-names))
-         (coding-system
-          (get-locale-coding-system locale)))
-
-      ;; Give preference to charset-language-name over language-name.
-      (if (and charset-language-name
-              (not
-               (equal (get-language-info language-name 'charset)
-                      (get-language-info charset-language-name 'charset))))
-         (setq language-name charset-language-name))
-
-      (when language-name
-
-       ;; If default-enable-multibyte-characters is nil,
-       ;; we are using single-byte characters,
-       ;; so the display table and terminal coding system are irrelevant.
-       (when default-enable-multibyte-characters
-         ;; Override default-terminal-coding-system in case the
-         ;; display coding can not be derived from the language
-         ;; environment.
-         (let ((default-terminal-coding-system coding-system))
-           (set-display-table-and-terminal-coding-system language-name)))
-
-       ;; Set the `keyboard-coding-system' if appropriate (tty
-       ;; only).  At least X and MS Windows can generate
-       ;; multilingual input.
-       (unless window-system
-         (let ((kcs (or coding-system
-                        (car (get-language-info language-name
-                                                'coding-system)))))
-           (if kcs (set-keyboard-coding-system kcs))))))))
-
 ;; Fixme: This ought to deal with the territory part of the locale
 ;; too, for setting things such as calendar holidays, ps-print paper
 ;; size, spelling dictionary.
 
-(defun set-locale-environment (&optional locale-name)
+(defun set-locale-environment (&optional locale-name display)
   "Set up multi-lingual environment for using LOCALE-NAME.
 This sets the language environment, the coding system priority,
 the default input method and sometimes other things.
@@ -2427,22 +2364,67 @@ or `@cyrillic'.
 
 If LOCALE-NAME is nil, its value is taken from the environment
 variables LC_ALL, LC_CTYPE and LANG (the first one that is set).
-On server frames, the environment of the emacsclient process is
-used.
 
 The locale names supported by your system can typically be found in a
 directory named `/usr/share/locale' or `/usr/lib/locale'.  LOCALE-NAME
 will be translated according to the table specified by
 `locale-translation-file-name'.
 
+If DISPLAY is non-nil, only set the keyboard coding system and
+the terminal coding system for the given display, and don't touch
+session-global parameters like the language environment.  DISPLAY
+may be a display id or a frame.
+
 See also `locale-charset-language-names', `locale-language-names',
 `locale-preferred-coding-systems' and `locale-coding-system'."
   (interactive "sSet environment for locale: ")
 
-  (let ((locale (get-locale-real-name locale-name)))
+  ;; Do this at runtime for the sake of binaries possibly transported
+  ;; to a system without X.
+  (setq locale-translation-file-name
+       (let ((files
+              '("/usr/lib/X11/locale/locale.alias" ; e.g. X11R6.4
+                "/usr/X11R6/lib/X11/locale/locale.alias" ; XFree86, e.g. RedHat 4.2
+                "/usr/openwin/lib/locale/locale.alias" ; e.g. Solaris 2.6
+                ;;
+                ;; The following name appears after the X-related names above,
+                ;; since the X-related names are what X actually uses.
+                "/usr/share/locale/locale.alias" ; GNU/Linux sans X
+                )))
+         (while (and files (not (file-exists-p (car files))))
+           (setq files (cdr files)))
+         (car files)))
+
+  (let ((locale locale-name))
+
+    (unless locale
+      ;; Use the first of these three environment variables
+      ;; that has a nonempty value.
+      (let ((vars '("LC_ALL" "LC_CTYPE" "LANG")))
+       (while (and vars
+                   (= 0 (length locale))) ; nil or empty string
+         (setq locale (getenv (pop vars))))))
+
+    (unless (or locale (not (fboundp 'mac-get-preference)))
+      (setq locale (mac-get-preference "AppleLocale"))
+      (unless locale
+       (let ((languages (mac-get-preference "AppleLanguages")))
+         (unless (= (length languages) 0) ; nil or empty vector
+           (setq locale (aref languages 0))))))
+    (unless (or locale (not (boundp 'mac-system-locale)))
+      (setq locale mac-system-locale))
 
     (when locale
 
+      ;; Translate "swedish" into "sv_SE.ISO8859-1", and so on,
+      ;; using the translation file that many systems have.
+      (when locale-translation-file-name
+       (with-temp-buffer
+         (insert-file-contents locale-translation-file-name)
+         (when (re-search-forward
+                (concat "^" (regexp-quote locale) ":?[ \t]+") nil t)
+           (setq locale (buffer-substring (point) (line-end-position))))))
+
       ;; Leave the system locales alone if the caller did not specify
       ;; an explicit locale name, as their defaults are set from
       ;; LC_MESSAGES and LC_TIME, not LC_CTYPE, and the user might not
@@ -2453,77 +2435,117 @@ See also `locale-charset-language-names', `locale-language-names',
 
       (setq locale (downcase locale))
 
-      (configure-display-for-locale locale)
-
       (let ((language-name
             (locale-name-match locale locale-language-names))
            (charset-language-name
             (locale-name-match locale locale-charset-language-names))
            (coding-system
-            (get-locale-coding-system locale)))
-
-       ;; Give preference to charset-language-name over language-name.
-       (if (and charset-language-name
-                (not
-                 (equal (get-language-info language-name 'charset)
-                        (get-language-info charset-language-name 'charset))))
-           (setq language-name charset-language-name))
+            (or (locale-name-match locale locale-preferred-coding-systems)
+                (when locale
+                  (if (string-match "\\.\\([^@]+\\)" locale)
+                      (locale-charset-to-coding-system
+                       (match-string 1 locale))))
+                (and (eq system-type 'macos) mac-system-coding-system))))
+
+       (if (consp language-name)
+           ;; locale-language-names specify both lang-env and coding.
+           ;; But, what specified in locale-preferred-coding-systems
+           ;; has higher priority.
+           (setq coding-system (or coding-system
+                                   (nth 1 language-name))
+                 language-name (car language-name))
+         ;; Otherwise, if locale is not listed in locale-language-names,
+         ;; use what listed in locale-charset-language-names.
+         (if (not language-name)
+             (setq language-name charset-language-name)))
 
        (when language-name
 
          ;; Set up for this character set.  This is now the right way
          ;; to do it for both unibyte and multibyte modes.
-         (set-language-environment language-name)
+         (unless display
+           (set-language-environment language-name))
+
+         ;; If default-enable-multibyte-characters is nil,
+         ;; we are using single-byte characters,
+         ;; so the display table and terminal coding system are irrelevant.
+         (when default-enable-multibyte-characters
+           (set-display-table-and-terminal-coding-system
+            language-name coding-system display))
+
+         ;; Set the `keyboard-coding-system' if appropriate (tty
+         ;; only).  At least X and MS Windows can generate
+         ;; multilingual input.
+         ;; XXX This was disabled unless `window-system', but that
+         ;; leads to buggy behaviour when a tty frame is opened
+         ;; later.  Setting the keyboard coding system has no adverse
+         ;; effect on X, so let's do it anyway. -- Lorentey
+         (let ((kcs (or coding-system
+                        (car (get-language-info language-name
+                                                'coding-system)))))
+           (if kcs (set-keyboard-coding-system kcs display)))
 
-         (setq locale-coding-system
-               (car (get-language-info language-name 'coding-priority))))
+         (unless display
+           (setq locale-coding-system
+                 (car (get-language-info language-name 'coding-priority)))))
 
-       (when coding-system
+       (when (and (not display)
+                  coding-system
+                  (not (coding-system-equal coding-system
+                                            locale-coding-system)))
          (prefer-coding-system coding-system)
          (setq locale-coding-system coding-system))))
 
-    ;; On Windows, override locale-coding-system, keyboard-coding-system,
-    ;; selection-coding-system with system codepage.
+    ;; On Windows, override locale-coding-system,
+    ;; keyboard-coding-system with system codepage.  Note:
+    ;; selection-coding-system is already set in w32select.c.
     (when (boundp 'w32-ansi-code-page)
       (let ((code-page-coding (intern (format "cp%d" w32-ansi-code-page))))
        (when (coding-system-p code-page-coding)
-         (setq locale-coding-system code-page-coding)
-         (set-selection-coding-system code-page-coding)
-         (set-keyboard-coding-system code-page-coding)
-         (set-terminal-coding-system code-page-coding))))
+         (unless display (setq locale-coding-system code-page-coding))
+         (set-keyboard-coding-system code-page-coding display)
+         (set-terminal-coding-system code-page-coding display))))
 
-    ;; On Darwin, file names are always encoded in utf-8, no matter the locale.
     (when (eq system-type 'darwin)
-      (setq default-file-name-coding-system 'utf-8))
+      ;; On Darwin, file names are always encoded in utf-8, no matter
+      ;; the locale.
+      (setq default-file-name-coding-system 'utf-8)
+      ;; Mac OS X's Terminal.app by default uses utf-8 regardless of
+      ;; the locale.
+      (when (and (null window-system)
+                (equal (getenv "TERM_PROGRAM") "Apple_Terminal"))
+       (set-terminal-coding-system 'utf-8)
+       (set-keyboard-coding-system 'utf-8)))
 
     ;; Default to A4 paper if we're not in a C, POSIX or US locale.
     ;; (See comments in Flocale_info.)
-    (let ((locale locale)
-         (paper (locale-info 'paper)))
-      (if paper
-         ;; This will always be null at the time of writing.
-         (cond
-          ((equal paper '(216 279))
-           (setq ps-paper-type 'letter))
-          ((equal paper '(210 297))
-           (setq ps-paper-type 'a4)))
-       (let ((vars '("LC_ALL" "LC_PAPER" "LANG")))
-         (while (and vars (= 0 (length locale)))
-           (setq locale (getenv (pop vars)))))
-       (when locale
-         ;; As of glibc 2.2.5, these are the only US Letter locales,
-         ;; and the rest are A4.
-         (setq ps-paper-type
-               (or (locale-name-match locale '(("c$" . letter)
-                                               ("posix$" . letter)
-                                               (".._us" . letter)
-                                               (".._pr" . letter)
-                                               (".._ca" . letter)
-                                               ("enu$" . letter) ; Windows
-                                               ("esu$" . letter)
-                                               ("enc$" . letter)
-                                               ("frc$" . letter)))
-                   'a4))))))
+    (unless display
+      (let ((locale locale)
+           (paper (locale-info 'paper)))
+       (if paper
+           ;; This will always be null at the time of writing.
+           (cond
+            ((equal paper '(216 279))
+             (setq ps-paper-type 'letter))
+            ((equal paper '(210 297))
+             (setq ps-paper-type 'a4)))
+         (let ((vars '("LC_ALL" "LC_PAPER" "LANG")))
+           (while (and vars (= 0 (length locale)))
+             (setq locale (getenv (pop vars)))))
+         (when locale
+           ;; As of glibc 2.2.5, these are the only US Letter locales,
+           ;; and the rest are A4.
+           (setq ps-paper-type
+                 (or (locale-name-match locale '(("c$" . letter)
+                                                 ("posix$" . letter)
+                                                 (".._us" . letter)
+                                                 (".._pr" . letter)
+                                                 (".._ca" . letter)
+                                                 ("enu$" . letter) ; Windows
+                                                 ("esu$" . letter)
+                                                 ("enc$" . letter)
+                                                 ("frc$" . letter)))
+                     'a4)))))))
   nil)
 \f
 ;;; Charset property