]> code.delx.au - gnu-emacs/blobdiff - lisp/faces.el
Merge from emacs--rel--22
[gnu-emacs] / lisp / faces.el
index 5c1e934f3b114c9585f11020cba8e092dd931305..e31622d9ba0eeb634829f073f5f8a0cf7e7146bd 100644 (file)
@@ -1,7 +1,7 @@
 ;;; faces.el --- Lisp faces
 
 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-;;   2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;;   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -10,7 +10,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -48,8 +48,8 @@
   "*A list specifying how face font selection chooses fonts.
 Each of the four symbols `:width', `:height', `:weight', and `:slant'
 must appear once in the list, and the list must not contain any other
-elements.  Font selection tries to find a best matching font for
-those face attributes first that appear first in the list.  For
+elements.  Font selection first tries to find a best matching font
+for those face attributes that appear before in the list.  For
 example, if `:slant' appears before `:height', font selection first
 tries to find a font with a suitable slant, even if this results in
 a font height that isn't optimal."
@@ -181,20 +181,16 @@ to NEW-FACE on frame NEW-FRAME."
 (defun internal-find-face (name &optional frame)
   "Retrieve the face named NAME.
 Return nil if there is no such face.
-If the optional argument FRAME is given, this gets the face NAME for
-that frame; otherwise, it uses the selected frame.
-If FRAME is the symbol t, then the global, non-frame face is returned.
-If NAME is already a face, it is simply returned."
+If NAME is already a face, it is simply returned.
+The optional argument FRAME is ignored."
   (facep name))
 (make-obsolete 'internal-find-face 'facep "21.1")
 
 
 (defun internal-get-face (name &optional frame)
   "Retrieve the face named NAME; error if there is none.
-If the optional argument FRAME is given, this gets the face NAME for
-that frame; otherwise, it uses the selected frame.
-If FRAME is the symbol t, then the global, non-frame face is returned.
-If NAME is already a face, it is simply returned."
+If NAME is already a face, it is simply returned.
+The optional argument FRAME is ignored."
   (or (facep name)
       (check-face name)))
 (make-obsolete 'internal-get-face "see `facep' and `check-face'." "21.1")
@@ -226,11 +222,12 @@ Value is FACE."
 
 (defun face-id (face &optional frame)
   "Return the internal ID of face with name FACE.
+If FACE is a face-alias, return the ID of the target face.
 The optional argument FRAME is ignored, since the internal face ID
 of a face name is the same for all frames."
   (check-face face)
-  (get face 'face))
-
+  (or (get face 'face)
+      (face-id (get face 'face-alias))))
 
 (defun face-equal (face1 face2 &optional frame)
   "Non-nil if faces FACE1 and FACE2 are equal.
@@ -248,8 +245,8 @@ If FRAME is t, report on the defaults for face FACE (for new frames).
 If FRAME is omitted or nil, use the selected frame."
   (let ((attrs
         '(:family :width :height :weight :slant :foreground
-          :foreground :background :underline :overline
-          :strike-through :box :inverse-video))
+          :background :underline :overline :strike-through
+          :box :inverse-video))
        (differs nil))
     (while (and attrs (not differs))
       (let* ((attr (pop attrs))
@@ -560,7 +557,7 @@ the default for new frames (this is done automatically each time an
 attribute is changed on all frames).
 
 ARGS must come in pairs ATTRIBUTE VALUE.  ATTRIBUTE must be a valid
-face attribute name.  All attributes can be set to `unspecified';
+face attribute name. All attributes can be set to `unspecified';
 this fact is not further mentioned below.
 
 The following attributes are recognized:
@@ -780,7 +777,7 @@ and DATA is a string, containing the raw bits of the bitmap."
   (set-face-attribute face frame :stipple (or stipple 'unspecified)))
 
 
-(defun set-face-underline-p (face underline-p &optional frame)
+(defun set-face-underline-p (face underline &optional frame)
   "Specify whether face FACE is underlined.
 UNDERLINE nil means FACE explicitly doesn't underline.
 UNDERLINE non-nil means FACE explicitly does underlining
@@ -791,7 +788,7 @@ Use `set-face-attribute' to ``unspecify'' underlining."
   (interactive
    (let ((list (read-face-and-attribute :underline)))
      (list (car list) (eq (car (cdr list)) t))))
-  (set-face-attribute face frame :underline underline-p))
+  (set-face-attribute face frame :underline underline))
 
 (define-obsolete-function-alias 'set-face-underline
                                 'set-face-underline-p "22.1")
@@ -859,10 +856,11 @@ of the default face.  Value is FACE."
 
 (defun read-face-name (prompt &optional string-describing-default multiple)
   "Read a face, defaulting to the face or faces on the char after point.
-If it has a `read-face-name' property, that overrides the `face' property.
-PROMPT describes what you will do with the face (don't end in a space).
-STRING-DESCRIBING-DEFAULT describes what default you will use
-if this function returns nil.
+If it has the property `read-face-name', that overrides the `face' property.
+PROMPT should be a string that describes what the caller will do with the face;
+it should not end in a space.
+STRING-DESCRIBING-DEFAULT should describe what default the caller will use if
+the user just types RET; you can omit it.
 If MULTIPLE is non-nil, return a list of faces (possibly only one).
 Otherwise, return a single face."
   (let ((faceprop (or (get-char-property (point) 'read-face-name)
@@ -947,7 +945,7 @@ an integer value."
                 (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
                                (internal-lisp-face-attribute-values attribute))
                        (mapcar #'(lambda (c) (cons c c))
-                               (x-defined-colors frame)))
+                               (defined-colors frame)))
              (mapcar #'(lambda (x) (cons (symbol-name x) x))
                      (internal-lisp-face-attribute-values attribute))))
            ((:foreground :background)
@@ -1019,7 +1017,7 @@ Value is the new attribute value."
                     (format "%s for face `%s' (default %s): "
                             name face default)
                   (format "%s for face `%s': " name face))
-                completion-alist)))
+                completion-alist nil nil nil nil default)))
     (if (equal value "") default value)))
 
 
@@ -1114,7 +1112,7 @@ Value is a property list of attribute names and new values."
                               result))))))
 
 (defun modify-face (&optional face foreground background stipple
-                             bold-p italic-p underline-p inverse-p frame)
+                             bold-p italic-p underline inverse-p frame)
   "Modify attributes of faces interactively.
 If optional argument FRAME is nil or omitted, modify the face used
 for newly created frame, i.e. the global face.
@@ -1129,7 +1127,7 @@ and the face and its settings are obtained by querying the user."
                          :stipple stipple
                          :bold bold-p
                          :italic italic-p
-                         :underline underline-p
+                         :underline underline
                          :inverse-video inverse-p)
     (setq face (read-face-name "Modify face"))
     (apply #'set-face-attribute face frame
@@ -1287,11 +1285,13 @@ If FRAME is omitted or nil, use the selected frame."
       (save-excursion
        (set-buffer standard-output)
        (dolist (f face)
+         (if (stringp f) (setq f (intern f)))
          (insert "Face: " (symbol-name f))
          (if (not (facep f))
              (insert "   undefined face.\n")
            (let ((customize-label "customize this face")
                  file-name)
+             (insert (concat " (" (propertize "sample" 'font-lock-face f) ")"))
              (princ (concat " (" customize-label ")\n"))
              (insert "Documentation: "
                      (or (face-documentation f)
@@ -1445,31 +1445,36 @@ If SPEC is nil, return nil."
 (defun face-spec-set (face spec &optional frame)
   "Set FACE's attributes according to the first matching entry in SPEC.
 FRAME is the frame whose frame-local face is set.  FRAME nil means
-do it on all frames.  See `defface' for information about SPEC.
-If SPEC is nil, do nothing."
+do it on all frames (and change the default for new frames).
+See `defface' for information about SPEC.  If SPEC is nil, do nothing."
   (let ((attrs (face-spec-choose spec frame)))
     (when spec
-      (face-spec-reset-face face frame))
+      (face-spec-reset-face face (or frame t)))
     (while attrs
       (let ((attribute (car attrs))
            (value (car (cdr attrs))))
        ;; Support some old-style attribute names and values.
        (case attribute
-         (:bold (setq attribute :weight value (if value 'bold 'normal)))
-         (:italic (setq attribute :slant value (if value 'italic 'normal)))
-         ((:foreground :background)
-          ;; Compatibility with 20.x.  Some bogus face specs seem to
-          ;; exist containing things like `:foreground nil'.
-          (if (null value) (setq value 'unspecified)))
-         (t (unless (assq attribute face-x-resources)
-              (setq attribute nil))))
+             (:bold (setq attribute :weight value (if value 'bold 'normal)))
+             (:italic (setq attribute :slant value (if value 'italic 'normal)))
+             ((:foreground :background)
+              ;; Compatibility with 20.x.  Some bogus face specs seem to
+              ;; exist containing things like `:foreground nil'.
+              (if (null value) (setq value 'unspecified)))
+             (t (unless (assq attribute face-x-resources)
+                  (setq attribute nil))))
        (when attribute
-         (set-face-attribute face frame attribute value)))
+         ;; If frame is nil, set the default for new frames.
+         ;; Existing frames are handled below.
+         (set-face-attribute face (or frame t) attribute value)))
       (setq attrs (cdr (cdr attrs)))))
-  ;; When we reset the face based on its spec, then it is unmodified
-  ;; as far as Custom is concerned.
-  (if (null frame)
-      (put (or (get face 'face-alias) face) 'face-modified nil)))
+  (unless frame
+    ;; When we reset the face based on its spec, then it is unmodified
+    ;; as far as Custom is concerned.
+    (put (or (get face 'face-alias) face) 'face-modified nil)
+    ;; Set each frame according to the rules implied by SPEC.
+    (dolist (frame (frame-list))
+      (face-spec-set face spec frame))))
 
 
 (defun face-attr-match-p (face attrs &optional frame)
@@ -1507,6 +1512,28 @@ If there is neither a user setting nor a default for FACE, return nil."
       (get face 'saved-face)
       (face-default-spec face)))
 
+(defsubst face-normalize-spec (spec)
+  "Return a normalized face-spec of SPEC."
+  (let (normalized-spec)
+    (while spec
+      (let ((attribute (car spec))
+           (value (car (cdr spec))))
+       ;; Support some old-style attribute names and values.
+       (case attribute
+         (:bold (setq attribute :weight value (if value 'bold 'normal)))
+         (:italic (setq attribute :slant value (if value 'italic 'normal)))
+         ((:foreground :background)
+          ;; Compatibility with 20.x.  Some bogus face specs seem to
+          ;; exist containing things like `:foreground nil'.
+          (if (null value) (setq value 'unspecified)))
+         (t (unless (assq attribute face-x-resources)
+              (setq attribute nil))))
+       (when attribute
+         (push attribute normalized-spec)
+         (push value normalized-spec)))
+      (setq spec (cdr (cdr spec))))
+    (nreverse normalized-spec)))
+
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Frame-type independent color support.
@@ -1517,7 +1544,8 @@ If there is neither a user setting nor a default for FACE, return nil."
   "Return a list of colors supported for a particular frame.
 The argument FRAME specifies which frame to try.
 The value may be different for frames on different display types.
-If FRAME doesn't support colors, the value is nil."
+If FRAME doesn't support colors, the value is nil.
+If FRAME is nil, that stands for the selected frame."
   (if (memq (framep (or frame (selected-frame))) '(x w32 mac))
       (xw-defined-colors frame)
     (mapcar 'car (tty-color-alist frame))))
@@ -1537,8 +1565,9 @@ If COLOR is the symbol `unspecified' or one of the strings
 
 (defun color-values (color &optional frame)
   "Return a description of the color named COLOR on frame FRAME.
-The value is a list of integer RGB values--\(RED GREEN BLUE\).
-These values appear to range from 0 65535; white is \(65535 65535 65535\).
+The value is a list of integer RGB values--(RED GREEN BLUE).
+These values appear to range from 0 to 65280 or 65535, depending
+on the system; white is \(65280 65280 65280\) or \(65535 65535 65535\).
 If FRAME is omitted or nil, use the selected frame.
 If FRAME cannot display COLOR, the value is nil.
 If COLOR is the symbol `unspecified' or one of the strings
@@ -1577,17 +1606,17 @@ If omitted or nil, that stands for the selected frame's display."
 (defcustom frame-background-mode nil
   "*The brightness of the background.
 Set this to the symbol `dark' if your background color is dark,
-`light' if your background is light, or nil (default) if you want Emacs
-to examine the brightness for you.  Don't set this variable with `setq';
-this won't have the expected effect."
+`light' if your background is light, or nil (automatic by default)
+if you want Emacs to examine the brightness for you.  Don't set this
+variable with `setq'; this won't have the expected effect."
   :group 'faces
   :set #'(lambda (var value)
           (set-default var value)
           (mapc 'frame-set-background-mode (frame-list)))
   :initialize 'custom-initialize-changed
-  :type '(choice (choice-item dark)
-                (choice-item light)
-                (choice-item :tag "default" nil)))
+  :type '(choice (const dark)
+                (const light)
+                (const :tag "automatic" nil)))
 
 
 (defun frame-set-background-mode (frame)
@@ -1598,11 +1627,13 @@ according to the `background-mode' and `display-type' frame parameters."
          (and (window-system frame)
               (x-get-resource "backgroundMode" "BackgroundMode")))
         (bg-color (frame-parameter frame 'background-color))
-        (tty-type (frame-parameter frame 'tty-type))
+        (terminal-bg-mode (terminal-parameter frame 'background-mode))
+        (tty-type (tty-type frame))
         (bg-mode
          (cond (frame-background-mode)
                (bg-resource
                 (intern (downcase bg-resource)))
+               (terminal-bg-mode)
                ((and (null (window-system frame))
                      ;; Unspecified frame background color can only
                      ;; happen on tty's.
@@ -1621,17 +1652,17 @@ according to the `background-mode' and `display-type' frame parameters."
                                        tty-type))
                     'dark
                   'light))
-               ((>= (apply '+ (x-color-values bg-color frame))
+               ((>= (apply '+ (color-values bg-color frame))
                    ;; Just looking at the screen, colors whose
                    ;; values add up to .6 of the white total
                    ;; still look dark to me.
-                   (* (apply '+ (x-color-values "white" frame)) .6))
+                   (* (apply '+ (color-values "white" frame)) .6))
                 'light)
                (t 'dark)))
         (display-type
          (cond ((null (window-system frame))
                 (if (tty-display-color-p frame) 'color 'mono))
-               ((x-display-color-p frame)
+               ((display-color-p frame)
                 'color)
                ((x-display-grayscale-p frame)
                 'grayscale)
@@ -1650,7 +1681,8 @@ according to the `background-mode' and `display-type' frame parameters."
        ;; be unmodified, so we can avoid consing in the common case.
        (dolist (face (face-list))
          (when (not (face-spec-match-p face
-                                       (face-user-default-spec face)
+                                       (face-normalize-spec
+                                        (face-user-default-spec face))
                                        (selected-frame)))
            (push face locally-modified-faces)))
        ;; Now change to the new frame parameters
@@ -1725,7 +1757,6 @@ the X resource ``reverseVideo'' is present, handle that.
 Value is the new frame created."
   (setq parameters (x-handle-named-frame-geometry parameters))
   (let ((visibility-spec (assq 'visibility parameters))
-       (frame-list (frame-list))
        (frame (x-create-frame `((visibility . nil) . ,parameters)))
        success)
     (unwind-protect
@@ -1734,14 +1765,18 @@ Value is the new frame created."
          (x-handle-reverse-video frame parameters)
          (frame-set-background-mode frame)
          (face-set-after-frame-default frame)
-         (if (or (null frame-list) (null visibility-spec))
-             (make-frame-visible frame)
-           (modify-frame-parameters frame (list visibility-spec)))
          ;; Arrange for the kill and yank functions to set and check the clipboard.
          (modify-frame-parameters
           frame '((interprogram-cut-function . x-select-text)))
          (modify-frame-parameters
           frame '((interprogram-paste-function . x-cut-buffer-or-selection-value)))
+         ;; Make sure the tool-bar is ready to be enabled.  The
+         ;; `tool-bar-lines' frame parameter will not take effect
+         ;; without this call.
+         (tool-bar-setup frame)
+         (if (null visibility-spec)
+             (make-frame-visible frame)
+           (modify-frame-parameters frame (list visibility-spec)))
          (setq success t))
       (unless success
        (delete-frame frame)))
@@ -1764,35 +1799,48 @@ Initialize colors of certain faces from frame parameters."
                          (face-attribute 'default :weight t))
       (set-face-attribute 'default frame :width
                          (face-attribute 'default :width t))))
-  (dolist (face (face-list))
-    ;; Don't let frame creation fail because of an invalid face spec.
-    (condition-case ()
-       (when (not (equal face 'default))
-         (face-spec-set face (face-user-default-spec face) frame)
-         (internal-merge-in-global-face face frame)
-         (when (and (memq (window-system frame) '(x w32 mac))
-                    (or (not (boundp 'inhibit-default-face-x-resources))
-                        (not (eq face 'default))))
-           (make-face-x-resource-internal face frame)))
-      (error nil)))
-  ;; Initialize attributes from frame parameters.
-  (let ((params '((foreground-color default :foreground)
-                 (background-color default :background)
-                 (border-color border :background)
-                 (cursor-color cursor :background)
-                 (scroll-bar-foreground scroll-bar :foreground)
-                 (scroll-bar-background scroll-bar :background)
-                 (mouse-color mouse :background))))
-    (dolist (param params)
-      (let ((frame-param (frame-parameter frame (nth 0 param)))
-           (face (nth 1 param))
-           (attr (nth 2 param)))
-       (when (and frame-param
-                  ;; Don't override face attributes explicitly
-                  ;; specified for new frames.
-                  (eq (face-attribute face attr t) 'unspecified))
-         (set-face-attribute face frame attr frame-param))))))
-
+  ;; Find attributes that should be initialized from frame parameters.
+  (let ((face-params '((foreground-color default :foreground)
+                      (background-color default :background)
+                      (border-color border :background)
+                      (cursor-color cursor :background)
+                      (scroll-bar-foreground scroll-bar :foreground)
+                      (scroll-bar-background scroll-bar :background)
+                      (mouse-color mouse :background)))
+       apply-params)
+    (dolist (param face-params)
+      (let* ((value (frame-parameter frame (nth 0 param)))
+            (face (nth 1 param))
+            (attr (nth 2 param))
+            (default-value (face-attribute face attr t)))
+       ;; Compile a list of face attributes to set, but don't set
+       ;; them yet.  The call to make-face-x-resource-internal,
+       ;; below, can change frame parameters, and the final set of
+       ;; frame parameters should be the ones acquired at this step.
+       (if (eq default-value 'unspecified)
+           ;; The face spec does not specify a new-frame value for
+           ;; this attribute.  Check if the existing frame parameter
+           ;; specifies it.
+           (if value
+               (push (list face frame attr value) apply-params))
+         ;; The face spec specifies a value for this attribute, to be
+         ;; applied to the face on all new frames.
+         (push (list face frame attr default-value) apply-params))))
+    ;; Initialize faces from face specs and X resources.  The
+    ;; condition-case prevents invalid specs from causing frame
+    ;; creation to fail.
+    (dolist (face (delq 'default (face-list)))
+      (condition-case ()
+         (progn
+           (face-spec-set face (face-user-default-spec face) frame)
+           (if (memq (window-system frame) '(x w32 mac))
+               (make-face-x-resource-internal face frame))
+           (internal-merge-in-global-face face frame))
+       (error nil)))
+    ;; Apply the attributes specified by frame parameters.  This
+    ;; rewrites parameters changed by make-face-x-resource-internal
+    (dolist (param apply-params)
+      (apply 'set-face-attribute param))))
 
 (defun tty-handle-reverse-video (frame parameters)
   "Handle the reverse-video frame parameter for terminal frames."
@@ -1823,8 +1871,6 @@ created."
     (unwind-protect
        (with-selected-frame frame
          (tty-handle-reverse-video frame (frame-parameters frame))
-         (frame-set-background-mode frame)
-         (face-set-after-frame-default frame)
 
          ;; Make sure the kill and yank functions do not touch the X clipboard.
          (modify-frame-parameters frame '((interprogram-cut-function . nil)))
@@ -1832,39 +1878,59 @@ created."
 
          (set-locale-environment nil frame)
          (tty-run-terminal-initialization frame)
+         (frame-set-background-mode frame)
+         (face-set-after-frame-default frame)
          (setq success t))
       (unless success
        (delete-frame frame)))
     frame))
 
-(defun tty-run-terminal-initialization (frame)
-  "Run the special initialization code for the terminal type of FRAME."
+(defun tty-find-type (pred type)
+  "Return the longest prefix of TYPE to which PRED returns non-nil.
+TYPE should be a tty type name such as \"xterm-16color\".
+
+The function tries only those prefixes that are followed by a
+dash or underscore in the original type name, like \"xterm\" in
+the above example."
+  (let (hyphend)
+    (while (and type
+               (not (funcall pred type)))
+      ;; Strip off last hyphen and what follows, then try again
+      (setq type
+           (if (setq hyphend (string-match "[-_][^-_]+$" type))
+               (substring type 0 hyphend)
+             nil))))
+  type)
+
+(defun tty-run-terminal-initialization (frame &optional type)
+  "Run the special initialization code for the terminal type of FRAME.
+The optional TYPE parameter may be used to override the autodetected
+terminal type to a different value."
+  (setq type (or type (tty-type frame)))
   ;; Load library for our terminal type.
   ;; User init file can set term-file-prefix to nil to prevent this.
   (with-selected-frame frame
-    (unless (null term-file-prefix)
-      (let* ((term (frame-parameter frame 'tty-type))
-            (term2 term)
-            hyphend term-init-func)
-       (while (and term
-                   (not (load (concat term-file-prefix term) t t)))
-         ;; Strip off last hyphen and what follows, then try again
-         (setq term
-               (if (setq hyphend (string-match "[-_][^-_]+$" term))
-                   (substring term 0 hyphend)
-                 nil)))
-       ;; The terminal file has been loaded, now find and call the
-       ;; terminal specific initialization function.
-       (while (and term2
-                   (not (fboundp
-                         (setq term-init-func (intern (concat "terminal-init-" term2))))))
-         ;; Strip off last hyphen and what follows, then try again
-         (setq term2
-               (if (setq hyphend (string-match "[-_][^-_]+$" term2))
-                   (substring term2 0 hyphend)
-                 nil)))
+    (unless (or (null term-file-prefix)
+               ;; Don't reinitialize the terminal each time a new
+               ;; frame is opened on it.
+               (terminal-parameter frame 'terminal-initted))
+      (let* (term-init-func)
+       ;; First, load the terminal initialization file, if it is
+       ;; available and it hasn't been loaded already.
+       (tty-find-type #'(lambda (type)
+                          (let ((file (locate-library (concat term-file-prefix type))))
+                            (and file
+                                 (or (assoc file load-history)
+                                     (load file t t)))))
+                      type)
+       ;; Next, try to find a matching initialization function, and call it.
+       (tty-find-type #'(lambda (type)
+                          (fboundp (setq term-init-func
+                                         (intern (concat "terminal-init-" type)))))
+                      type)
        (when (fboundp term-init-func)
-         (funcall term-init-func))))))
+         (funcall term-init-func))
+       (set-terminal-parameter frame 'terminal-initted term-init-func)))))
 
 ;; Called from C function init_display to initialize faces of the
 ;; dumped terminal frame on startup.
@@ -1961,6 +2027,28 @@ created."
   :group 'basic-faces
   :version "22.1")
 
+(defface link
+  '((((class color) (min-colors 88) (background light))
+     :foreground "blue1" :underline t)
+    (((class color) (background light))
+     :foreground "blue" :underline t)
+    (((class color) (min-colors 88) (background dark))
+     :foreground "cyan1" :underline t)
+    (((class color) (background dark))
+     :foreground "cyan" :underline t)
+    (t :inherit underline))
+  "Basic face for unvisited links."
+  :group 'basic-faces
+  :version "22.1")
+
+(defface link-visited
+  '((default :inherit link)
+    (((class color) (background light)) :foreground "magenta4")
+    (((class color) (background dark)) :foreground "violet"))
+  "Basic face for visited links."
+  :group 'basic-faces
+  :version "22.1")
+
 (defface highlight
   '((((class color) (min-colors 88) (background light))
      :background "darkseagreen2")
@@ -1976,16 +2064,6 @@ created."
   "Basic face for highlighting."
   :group 'basic-faces)
 
-(defface mode-line-highlight
-  '((((class color) (min-colors 88))
-     :box (:line-width 2 :color "grey40" :style released-button))
-    (t
-     :inherit highlight))
-  "Basic mode line face for highlighting."
-  :version "22.1"
-  :group 'modeline
-  :group 'basic-faces)
-
 (defface region
   '((((class color) (min-colors 88) (background dark))
      :background "blue3")
@@ -2027,7 +2105,7 @@ created."
     (t :inverse-video t))
   "Basic face for highlighting trailing whitespace."
   :version "21.1"
-  :group 'whitespace           ; like `show-trailing-whitespace'
+  :group 'whitespace-faces     ; like `show-trailing-whitespace'
   :group 'basic-faces)
 
 (defface escape-glyph
@@ -2038,7 +2116,7 @@ created."
     ;; red4 is too dark, but some say blue is too loud.
     ;; brown seems to work ok. -- rms.
     (t :foreground "brown"))
-  "Face for characters displayed as ^-sequences or \-sequences."
+  "Face for characters displayed as sequences using `^' or `\\'."
   :group 'basic-faces
   :version "22.1")
 
@@ -2050,6 +2128,12 @@ created."
   :group 'basic-faces
   :version "22.1")
 
+(defgroup mode-line-faces nil
+  "Faces used in the mode line."
+  :group 'mode-line
+  :group 'faces
+  :version "22.1")
+
 (defface mode-line
   '((((class color) (min-colors 88))
      :box (:line-width -1 :style released-button)
@@ -2058,7 +2142,7 @@ created."
      :inverse-video t))
   "Basic mode line face for selected window."
   :version "21.1"
-  :group 'modeline
+  :group 'mode-line-faces
   :group 'basic-faces)
 
 (defface mode-line-inactive
@@ -2074,13 +2158,31 @@ created."
      :foreground "grey80" :background "grey30"))
   "Basic mode line face for non-selected windows."
   :version "22.1"
-  :group 'modeline
+  :group 'mode-line-faces
+  :group 'basic-faces)
+
+(defface mode-line-highlight
+  '((((class color) (min-colors 88))
+     :box (:line-width 2 :color "grey40" :style released-button))
+    (t
+     :inherit highlight))
+  "Basic mode line face for highlighting."
+  :version "22.1"
+  :group 'mode-line-faces
+  :group 'basic-faces)
+
+(defface mode-line-buffer-id
+  '((t (:weight bold)))
+  "Face used for buffer identification parts of the mode line."
+  :version "22.1"
+  :group 'mode-line-faces
   :group 'basic-faces)
 
 ;; Make `modeline' an alias for `mode-line', for compatibility.
 (put 'modeline 'face-alias 'mode-line)
 (put 'modeline-inactive 'face-alias 'mode-line-inactive)
 (put 'modeline-highlight 'face-alias 'mode-line-highlight)
+(put 'modeline-buffer-id 'face-alias 'mode-line-buffer-id)
 
 (defface header-line
   '((default
@@ -2121,7 +2223,6 @@ created."
   '((((type tty)) :inherit mode-line-inactive))
   "Face used for vertical window dividers on ttys."
   :version "22.1"
-  :group 'modeline
   :group 'basic-faces)
 
 (defface minibuffer-prompt
@@ -2129,7 +2230,7 @@ created."
     ;; Don't use blue because many users of the MS-DOS port customize
     ;; their foreground color to be blue.
     (((type pc)) :foreground "magenta")
-    (t :foreground "dark blue"))
+    (t :foreground "medium blue"))
   "Face for minibuffer prompts.
 By default, Emacs automatically adds this face to the value of
 `minibuffer-prompt-properties', which is a list of text properties
@@ -2152,19 +2253,19 @@ used to display the prompt text."
   :group 'frames
   :group 'basic-faces)
 
-(defface scroll-bar '()
+(defface scroll-bar '((t nil))
   "Basic face for the scroll bar colors under X."
   :version "21.1"
   :group 'frames
   :group 'basic-faces)
 
-(defface border '()
+(defface border '((t nil))
   "Basic face for the frame border under X."
   :version "21.1"
   :group 'frames
   :group 'basic-faces)
 
-(defface cursor '()
+(defface cursor '((t nil))
   "Basic face for the cursor color under X.
 Note: Other faces cannot inherit from the cursor face."
   :version "21.1"
@@ -2173,7 +2274,7 @@ Note: Other faces cannot inherit from the cursor face."
 
 (put 'cursor 'face-no-inherit t)
 
-(defface mouse '()
+(defface mouse '((t nil))
   "Basic face for the mouse color under X."
   :version "21.1"
   :group 'mouse