comparison lisp/faces.el @ 209:41ff10fd062f r20-4b3

Import from CVS: tag r20-4b3
author cvs
date Mon, 13 Aug 2007 10:04:58 +0200
parents
children 78f53ef88e17
comparison
equal deleted inserted replaced
208:f427b8ec4379 209:41ff10fd062f
1 ;;; faces.el --- Lisp interface to the C "face" structure
2
3 ;; Copyright (C) 1992-4, 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) 1995 Board of Trustees, University of Illinois
5 ;; Copyright (C) 1995, 1996 Ben Wing
6
7 ;; Author: Ben Wing <wing@666.com>
8 ;; Keywords: faces, internal, dumped
9
10 ;; This file is part of XEmacs.
11
12 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
26
27 ;;; Synched up with: Not synched with FSF. Almost completely divergent.
28
29 ;;; Commentary:
30
31 ;; This file is dumped with XEmacs.
32
33 ;; face implementation #1 (used Lisp vectors and parallel C vectors;
34 ;; FSFmacs still uses this) authored by Jamie Zawinski <jwz@netscape.com>
35 ;; pre Lucid-Emacs 19.0.
36
37 ;; face implementation #2 (used one face object per frame per face)
38 ;; authored by Jamie Zawinski for 19.9.
39
40 ;; face implementation #3 (use one face object per face) originally
41 ;; authored for 19.12 by Chuck Thompson <cthomp@cs.uiuc.edu>,
42 ;; rewritten by Ben Wing with the advent of specifiers.
43
44
45 ;;; Some stuff in FSF's faces.el is in our x-faces.el.
46
47 ;;; Code:
48
49 (defun read-face-name (prompt)
50 (let (face)
51 (while (= (length face) 0) ; nil or ""
52 (setq face (completing-read prompt
53 (mapcar (lambda (x) (list (symbol-name x)))
54 (face-list))
55 nil t)))
56 (intern face)))
57
58 (defun face-interactive (what &optional bool)
59 (let* ((fn (intern (concat "face-" what "-instance")))
60 (face (read-face-name (format "Set %s of face: " what)))
61 (default (if (fboundp fn)
62 ;; #### we should distinguish here between
63 ;; explicitly setting the value to be the
64 ;; same as the default face's value, and
65 ;; not setting a value at all.
66 (funcall fn face)))
67 (value (if bool
68 (y-or-n-p (format "Should face %s be %s? "
69 (symbol-name face) bool))
70 (read-string (format "Set %s of face %s to: "
71 what (symbol-name face))
72 (cond ((font-instance-p default)
73 (font-instance-name default))
74 ((color-instance-p default)
75 (color-instance-name default))
76 ((image-instance-p default)
77 (image-instance-file-name default))
78 (t default))))))
79 (list face (if (equal value "") nil value))))
80
81 (defconst built-in-face-specifiers
82 (built-in-face-specifiers)
83 "A list of the built-in face properties that are specifiers.")
84
85 (defun face-property (face property &optional locale tag-set exact-p)
86 "Return FACE's value of the given PROPERTY.
87
88 If LOCALE is omitted, the FACE's actual value for PROPERTY will be
89 returned. For built-in properties, this will be a specifier object
90 of a type appropriate to the property (e.g. a font or color
91 specifier). For other properties, this could be anything.
92
93 If LOCALE is supplied, then instead of returning the actual value,
94 the specification(s) for the given locale or locale type will
95 be returned. This will only work if the actual value of
96 PROPERTY is a specifier (this will always be the case for built-in
97 properties, but not or not may apply to user-defined properties).
98 If the actual value of PROPERTY is not a specifier, this value
99 will simply be returned regardless of LOCALE.
100
101 The return value will be a list of instantiators (e.g. strings
102 specifying a font or color name), or a list of specifications, each
103 of which is a cons of a locale and a list of instantiators.
104 Specifically, if LOCALE is a particular locale (a buffer, window,
105 frame, device, or 'global), a list of instantiators for that locale
106 will be returned. Otherwise, if LOCALE is a locale type (one of
107 the symbols 'buffer, 'window, 'frame, or 'device), the specifications
108 for all locales of that type will be returned. Finally, if LOCALE is
109 'all, the specifications for all locales of all types will be returned.
110
111 The specifications in a specifier determine what the value of
112 PROPERTY will be in a particular \"domain\" or set of circumstances,
113 which is typically a particular Emacs window along with the buffer
114 it contains and the frame and device it lies within. The value
115 is derived from the instantiator associated with the most specific
116 locale (in the order buffer, window, frame, device, and 'global)
117 that matches the domain in question. In other words, given a domain
118 (i.e. an Emacs window, usually), the specifier for PROPERTY will first
119 be searched for a specification whose locale is the buffer contained
120 within that window; then for a specification whose locale is the window
121 itself; then for a specification whose locale is the frame that the
122 window is contained within; etc. The first instantiator that is
123 valid for the domain (usually this means that the instantiator is
124 recognized by the device [i.e. the X server or TTY device] that the
125 domain is on. The function `face-property-instance' actually does
126 all this, and is used to determine how to display the face.
127
128 See `set-face-property' for the built-in property-names."
129
130 (setq face (get-face face))
131 (let ((value (get face property)))
132 (if (and locale
133 (or (memq property built-in-face-specifiers)
134 (specifierp value)))
135 (setq value (specifier-specs value locale tag-set exact-p)))
136 value))
137
138 (defun convert-face-property-into-specifier (face property)
139 "Convert PROPERTY on FACE into a specifier, if it's not already."
140 (setq face (get-face face))
141 (let ((specifier (get face property)))
142 ;; if a user-property does not have a specifier but a
143 ;; locale was specified, put a specifier there.
144 ;; If there was already a value there, convert it to a
145 ;; specifier with the value as its 'global instantiator.
146 (unless (specifierp specifier)
147 (let ((new-specifier (make-specifier 'generic)))
148 (if (or (not (null specifier))
149 ;; make sure the nil returned from `get' wasn't
150 ;; actually the value of the property
151 (null (get face property t)))
152 (add-spec-to-specifier new-specifier specifier))
153 (setq specifier new-specifier)
154 (put face property specifier)))))
155
156 (defun face-property-instance (face property
157 &optional domain default no-fallback)
158 "Return the instance of FACE's PROPERTY in the specified DOMAIN.
159
160 Under most circumstances, DOMAIN will be a particular window,
161 and the returned instance describes how the specified property
162 actually is displayed for that window and the particular buffer
163 in it. Note that this may not be the same as how the property
164 appears when the buffer is displayed in a different window or
165 frame, or how the property appears in the same window if you
166 switch to another buffer in that window; and in those cases,
167 the returned instance would be different.
168
169 The returned instance will typically be a color-instance,
170 font-instance, or pixmap-instance object, and you can query
171 it using the appropriate object-specific functions. For example,
172 you could use `color-instance-rgb-components' to find out the
173 RGB (red, green, and blue) components of how the 'background
174 property of the 'highlight face is displayed in a particular
175 window. The results might be different from the results
176 you would get for another window (perhaps the user
177 specified a different color for the frame that window is on;
178 or perhaps the same color was specified but the window is
179 on a different X server, and that X server has different RGB
180 values for the color from this one).
181
182 DOMAIN defaults to the selected window if omitted.
183
184 DOMAIN can be a frame or device, instead of a window. The value
185 returned for a such a domain is used in special circumstances
186 when a more specific domain does not apply; for example, a frame
187 value might be used for coloring a toolbar, which is conceptually
188 attached to a frame rather than a particular window. The value
189 is also useful in determining what the value would be for a
190 particular window within the frame or device, if it is not
191 overridden by a more specific specification.
192
193 If PROPERTY does not name a built-in property, its value will
194 simply be returned unless it is a specifier object, in which case
195 it will be instanced using `specifier-instance'.
196
197 Optional arguments DEFAULT and NO-FALLBACK are the same as in
198 `specifier-instance'."
199
200 (setq face (get-face face))
201 (let ((value (get face property)))
202 (if (specifierp value)
203 (setq value (specifier-instance value domain default no-fallback)))
204 value))
205
206 (defun face-property-matching-instance (face property matchspec
207 &optional domain default
208 no-fallback)
209 "Return the instance of FACE's PROPERTY matching MATCHSPEC in DOMAIN.
210 Currently the only useful value for MATCHSPEC is a charset, when used
211 in conjunction with the face's font; this allows you to retrieve a
212 font that can be used to display a particular charset, rather than just
213 any font.
214
215 Other than MATCHSPEC, this function is identical to `face-property-instance'.
216 See also `specifier-matching-instance' for a fuller description of the
217 matching process."
218
219 (setq face (get-face face))
220 (let ((value (get face property)))
221 (if (specifierp value)
222 (setq value (specifier-matching-instance value matchspec domain
223 default no-fallback)))
224 value))
225
226 (defun set-face-property (face property value &optional locale tag-set
227 how-to-add)
228 "Change a property of a FACE.
229
230 NOTE: If you want to remove a property from a face, use `remove-face-property'
231 rather than attempting to set a value of nil for the property.
232
233 For built-in properties, the actual value of the property is a
234 specifier and you cannot change this; but you can change the
235 specifications within the specifier, and that is what this function
236 will do. For user-defined properties, you can use this function
237 to either change the actual value of the property or, if this value
238 is a specifier, change the specifications within it.
239
240 If PROPERTY is a built-in property, the specifications to be added to
241 this property can be supplied in many different ways:
242
243 -- If VALUE is a simple instantiator (e.g. a string naming a font or
244 color) or a list of instantiators, then the instantiator(s) will
245 be added as a specification of the property for the given LOCALE
246 (which defaults to 'global if omitted).
247 -- If VALUE is a list of specifications (each of which is a cons of
248 a locale and a list of instantiators), then LOCALE must be nil
249 (it does not make sense to explicitly specify a locale in this
250 case), and specifications will be added as given.
251 -- If VALUE is a specifier (as would be returned by `face-property'
252 if no LOCALE argument is given), then some or all of the
253 specifications in the specifier will be added to the property.
254 In this case, the function is really equivalent to
255 `copy-specifier' and LOCALE has the same semantics (if it is
256 a particular locale, the specification for the locale will be
257 copied; if a locale type, specifications for all locales of
258 that type will be copied; if nil or 'all, then all
259 specifications will be copied).
260
261 HOW-TO-ADD should be either nil or one of the symbols 'prepend,
262 'append, 'remove-tag-set-prepend, 'remove-tag-set-append, 'remove-locale,
263 'remove-locale-type, or 'remove-all. See `copy-specifier' and
264 `add-spec-to-specifier' for a description of what each of
265 these means. Most of the time, you do not need to worry about
266 this argument; the default behavior usually is fine.
267
268 In general, it is OK to pass an instance object (e.g. as returned
269 by `face-property-instance') as an instantiator in place of
270 an actual instantiator. In such a case, the instantiator used
271 to create that instance object will be used (for example, if
272 you set a font-instance object as the value of the 'font
273 property, then the font name used to create that object will
274 be used instead). If some cases, however, doing this
275 conversion does not make sense, and this will be noted in
276 the documentation for particular types of instance objects.
277
278 If PROPERTY is not a built-in property, then this function will
279 simply set its value if LOCALE is nil. However, if LOCALE is
280 given, then this function will attempt to add VALUE as the
281 instantiator for the given LOCALE, using `add-spec-to-specifier'.
282 If the value of the property is not a specifier, it will
283 automatically be converted into a 'generic specifier.
284
285
286 The following symbols have predefined meanings:
287
288 foreground The foreground color of the face.
289 For valid instantiators, see `color-specifier-p'.
290
291 background The background color of the face.
292 For valid instantiators, see `color-specifier-p'.
293
294 font The font used to display text covered by this face.
295 For valid instantiators, see `font-specifier-p'.
296
297 display-table The display table of the face.
298 This should be a vector of 256 elements.
299
300 background-pixmap The pixmap displayed in the background of the face.
301 Only used by faces on X devices.
302 For valid instantiators, see `image-specifier-p'.
303
304 underline Underline all text covered by this face.
305 For valid instantiators, see `face-boolean-specifier-p'.
306
307 strikethru Draw a line through all text covered by this face.
308 For valid instantiators, see `face-boolean-specifier-p'.
309
310 highlight Highlight all text covered by this face.
311 Only used by faces on TTY devices.
312 For valid instantiators, see `face-boolean-specifier-p'.
313
314 dim Dim all text covered by this face.
315 Only used by faces on TTY devices.
316 For valid instantiators, see `face-boolean-specifier-p'.
317
318 blinking Blink all text covered by this face.
319 Only used by faces on TTY devices.
320 For valid instantiators, see `face-boolean-specifier-p'.
321
322 reverse Reverse the foreground and background colors.
323 Only used by faces on TTY devices.
324 For valid instantiators, see `face-boolean-specifier-p'.
325
326 doc-string Description of what the face's normal use is.
327 NOTE: This is not a specifier, unlike all
328 the other built-in properties, and cannot
329 contain locale-specific values."
330
331 (setq face (get-face face))
332 (if (memq property built-in-face-specifiers)
333 (set-specifier (get face property) value locale tag-set how-to-add)
334
335 ;; This section adds user defined properties.
336 (if (not locale)
337 (put face property value)
338 (convert-face-property-into-specifier face property)
339 (add-spec-to-specifier (get face property) value locale tag-set
340 how-to-add)))
341 value)
342
343 (defun remove-face-property (face property &optional locale tag-set exact-p)
344 "Remove a property from a face.
345 For built-in properties, this is analogous to `remove-specifier'.
346 See `remove-specifier' for the meaning of the LOCALE, TAG-SET, and EXACT-P
347 arguments."
348 (or locale (setq locale 'all))
349 (if (memq property built-in-face-specifiers)
350 (remove-specifier (face-property face property) locale tag-set exact-p)
351 (if (eq locale 'all)
352 (remprop (get-face face) property)
353 (convert-face-property-into-specifier face property)
354 (remove-specifier (face-property face property) locale tag-set
355 exact-p))))
356
357 (defun reset-face (face &optional locale tag-set exact-p)
358 "Clear all existing built-in specifications from FACE.
359 This makes FACE inherit all its display properties from 'default.
360 WARNING: Be absolutely sure you want to do this!!! It is a dangerous
361 operation and is not undoable.
362
363 The arguments LOCALE, TAG-SET and EXACT-P are the same as for
364 `remove-specifier'."
365 (mapc (lambda (x)
366 (remove-specifier (face-property face x) locale tag-set exact-p))
367 built-in-face-specifiers)
368 nil)
369
370 (defun set-face-parent (face parent &optional locale tag-set how-to-add)
371 "Set the parent of FACE to PARENT, for all properties.
372 This makes all properties of FACE inherit from PARENT."
373 (setq parent (get-face parent))
374 (mapcar (lambda (x)
375 (set-face-property face x (vector parent) locale tag-set
376 how-to-add))
377 (delq 'display-table
378 (delq 'background-pixmap
379 (copy-sequence built-in-face-specifiers))))
380 (set-face-background-pixmap face (vector 'inherit ':face parent)
381 locale tag-set how-to-add)
382 nil)
383
384 (defun face-doc-string (face)
385 "Return the documentation string for FACE."
386 (face-property face 'doc-string))
387
388 (defun set-face-doc-string (face doc-string)
389 "Change the documentation string of FACE to DOC-STRING."
390 (interactive (face-interactive "doc-string"))
391 (set-face-property face 'doc-string doc-string))
392
393 (defun face-font-name (face &optional domain charset)
394 "Return the font name of the given face, or nil if it is unspecified.
395 DOMAIN is as in `face-font-instance'."
396 (let ((f (face-font-instance face domain charset)))
397 (and f (font-instance-name f))))
398
399 (defun face-font (face &optional locale tag-set exact-p)
400 "Return the font of the given face, or nil if it is unspecified.
401
402 FACE may be either a face object or a symbol representing a face.
403
404 LOCALE may be a locale (the instantiators for that particular locale
405 will be returned), a locale type (the specifications for all locales
406 of that type will be returned), 'all (all specifications will be
407 returned), or nil (the actual specifier object will be returned).
408
409 See `face-property' for more information."
410 (face-property face 'font locale tag-set exact-p))
411
412 (defun face-font-instance (face &optional domain charset)
413 "Return the instance of the given face's font in the given domain.
414
415 FACE may be either a face object or a symbol representing a face.
416
417 Normally DOMAIN will be a window or nil (meaning the selected window),
418 and an instance object describing how the font appears in that
419 particular window and buffer will be returned.
420
421 See `face-property-instance' for more information."
422 (if charset
423 (face-property-matching-instance face 'font charset domain)
424 (face-property-instance face 'font domain)))
425
426 (defun set-face-font (face font &optional locale tag-set how-to-add)
427 "Change the font of the given face.
428
429 FACE may be either a face object or a symbol representing a face.
430
431 FONT should be an instantiator (see `font-specifier-p'), a list of
432 instantiators, an alist of specifications (each mapping a
433 locale to an instantiator list), or a font specifier object.
434
435 If FONT is an alist, LOCALE must be omitted. If FONT is a
436 specifier object, LOCALE can be a locale, a locale type, 'all,
437 or nil; see `copy-specifier' for its semantics. Otherwise LOCALE
438 specifies the locale under which the specified instantiator(s)
439 will be added, and defaults to 'global.
440
441 See `set-face-property' for more information."
442 (interactive (face-interactive "font"))
443 (set-face-property face 'font font locale tag-set how-to-add))
444
445 (defun face-foreground (face &optional locale tag-set exact-p)
446 "Return the foreground of the given face, or nil if it is unspecified.
447
448 FACE may be either a face object or a symbol representing a face.
449
450 LOCALE may be a locale (the instantiators for that particular locale
451 will be returned), a locale type (the specifications for all locales
452 of that type will be returned), 'all (all specifications will be
453 returned), or nil (the actual specifier object will be returned).
454
455 See `face-property' for more information."
456 (face-property face 'foreground locale tag-set exact-p))
457
458 (defun face-foreground-instance (face &optional domain default no-fallback)
459 "Return the instance of the given face's foreground in the given domain.
460
461 FACE may be either a face object or a symbol representing a face.
462
463 Normally DOMAIN will be a window or nil (meaning the selected window),
464 and an instance object describing how the foreground appears in that
465 particular window and buffer will be returned.
466
467 See `face-property-instance' for more information."
468 (face-property-instance face 'foreground domain default no-fallback))
469
470 (defun face-foreground-name (face &optional domain default no-fallback)
471 "Return the name of the given face's foreground color in the given domain.
472
473 FACE may be either a face object or a symbol representing a face.
474
475 Normally DOMAIN will be a window or nil (meaning the selected window),
476 and an instance object describing how the background appears in that
477 particular window and buffer will be returned.
478
479 See `face-property-instance' for more information."
480 (color-instance-name (face-foreground-instance
481 face domain default no-fallback)))
482
483 (defun set-face-foreground (face color &optional locale tag-set how-to-add)
484 "Change the foreground of the given face.
485
486 FACE may be either a face object or a symbol representing a face.
487
488 COLOR should be an instantiator (see `color-specifier-p'), a list of
489 instantiators, an alist of specifications (each mapping a locale to
490 an instantiator list), or a color specifier object.
491
492 If COLOR is an alist, LOCALE must be omitted. If COLOR is a
493 specifier object, LOCALE can be a locale, a locale type, 'all,
494 or nil; see `copy-specifier' for its semantics. Otherwise LOCALE
495 specifies the locale under which the specified instantiator(s)
496 will be added, and defaults to 'global.
497
498 See `set-face-property' for more information."
499 (interactive (face-interactive "foreground"))
500 (set-face-property face 'foreground color locale tag-set how-to-add))
501
502 (defun face-background (face &optional locale tag-set exact-p)
503 "Return the background of the given face, or nil if it is unspecified.
504
505 FACE may be either a face object or a symbol representing a face.
506
507 LOCALE may be a locale (the instantiators for that particular locale
508 will be returned), a locale type (the specifications for all locales
509 of that type will be returned), 'all (all specifications will be
510 returned), or nil (the actual specifier object will be returned).
511
512 See `face-property' for more information."
513 (face-property face 'background locale tag-set exact-p))
514
515 (defun face-background-instance (face &optional domain default no-fallback)
516 "Return the instance of the given face's background in the given domain.
517
518 FACE may be either a face object or a symbol representing a face.
519
520 Normally DOMAIN will be a window or nil (meaning the selected window),
521 and an instance object describing how the background appears in that
522 particular window and buffer will be returned.
523
524 See `face-property-instance' for more information."
525 (face-property-instance face 'background domain default no-fallback))
526
527 (defun face-background-name (face &optional domain default no-fallback)
528 "Return the name of the given face's background color in the given domain.
529
530 FACE may be either a face object or a symbol representing a face.
531
532 Normally DOMAIN will be a window or nil (meaning the selected window),
533 and an instance object describing how the background appears in that
534 particular window and buffer will be returned.
535
536 See `face-property-instance' for more information."
537 (color-instance-name (face-background-instance
538 face domain default no-fallback)))
539
540 (defun set-face-background (face color &optional locale tag-set how-to-add)
541 "Change the background of the given face.
542
543 FACE may be either a face object or a symbol representing a face.
544
545 COLOR should be an instantiator (see `color-specifier-p'), a list of
546 instantiators, an alist of specifications (each mapping a locale to
547 an instantiator list), or a color specifier object.
548
549 If COLOR is an alist, LOCALE must be omitted. If COLOR is a
550 specifier object, LOCALE can be a locale, a locale type, 'all,
551 or nil; see `copy-specifier' for its semantics. Otherwise LOCALE
552 specifies the locale under which the specified instantiator(s)
553 will be added, and defaults to 'global.
554
555 See `set-face-property' for more information."
556 (interactive (face-interactive "background"))
557 (set-face-property face 'background color locale tag-set how-to-add))
558
559 (defun face-background-pixmap (face &optional locale tag-set exact-p)
560 "Return the background pixmap of the given face, or nil if it is unspecified.
561 This property is only used on X devices.
562
563 FACE may be either a face object or a symbol representing a face.
564
565 LOCALE may be a locale (the instantiators for that particular locale
566 will be returned), a locale type (the specifications for all locales
567 of that type will be returned), 'all (all specifications will be
568 returned), or nil (the actual specifier object will be returned).
569
570 See `face-property' for more information."
571 (face-property face 'background-pixmap locale tag-set exact-p))
572
573 (defun face-background-pixmap-instance (face &optional domain default
574 no-fallback)
575 "Return the instance of the given face's background pixmap in the given domain.
576
577 FACE may be either a face object or a symbol representing a face.
578
579 Normally DOMAIN will be a window or nil (meaning the selected window),
580 and an instance object describing how the background appears in that
581 particular window and buffer will be returned.
582
583 See `face-property-instance' for more information."
584 (face-property-instance face 'background-pixmap domain default no-fallback))
585
586 (defun set-face-background-pixmap (face pixmap &optional locale tag-set
587 how-to-add)
588 "Change the background pixmap of the given face.
589 This property is only used on X devices.
590
591 FACE may be either a face object or a symbol representing a face.
592
593 PIXMAP should be an instantiator (see `image-specifier-p'), a list
594 of instantiators, an alist of specifications (each mapping a locale
595 to an instantiator list), or an image specifier object.
596
597 If PIXMAP is an alist, LOCALE must be omitted. If PIXMAP is a
598 specifier object, LOCALE can be a locale, a locale type, 'all,
599 or nil; see `copy-specifier' for its semantics. Otherwise LOCALE
600 specifies the locale under which the specified instantiator(s)
601 will be added, and defaults to 'global.
602
603 See `set-face-property' for more information."
604 (interactive (face-interactive "background-pixmap"))
605 (set-face-property face 'background-pixmap pixmap locale tag-set how-to-add))
606
607 (defun face-display-table (face &optional locale tag-set exact-p)
608 "Return the display table of the given face.
609
610 A vector (as returned by `make-display-table') will be returned.
611
612 LOCALE may be a locale (the instantiators for that particular locale
613 will be returned), a locale type (the specifications for all locales
614 of that type will be returned), 'all (all specifications will be
615 returned), or nil (the actual specifier object will be returned).
616
617 See `face-property' for more information."
618 (face-property face 'display-table locale tag-set exact-p))
619
620 (defun face-display-table-instance (face &optional domain default no-fallback)
621 "Return the instance of FACE's display table in DOMAIN.
622 A vector (as returned by `make-display-table') will be returned.
623
624 See `face-property-instance' for the semantics of the DOMAIN argument."
625 (face-property-instance face 'display-table domain default no-fallback))
626
627 (defun set-face-display-table (face display-table &optional locale tag-set
628 how-to-add)
629 "Change the display table of the given face.
630 DISPLAY-TABLE should be a vector as returned by `make-display-table'.
631
632 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
633 HOW-TO-ADD arguments."
634 (interactive (face-interactive "display-table"))
635 (set-face-property face 'display-table display-table locale tag-set
636 how-to-add))
637
638 ;; The following accessors and mutators are, IMHO, good
639 ;; implementation. Cf. with `make-face-bold'.
640
641 (defun face-underline-p (face &optional domain default no-fallback)
642 "Return whether the given face is underlined.
643 See `face-property-instance' for the semantics of the DOMAIN argument."
644 (face-property-instance face 'underline domain default no-fallback))
645
646 (defun set-face-underline-p (face underline-p &optional locale tag-set
647 how-to-add)
648 "Change whether the given face is underlined.
649 UNDERLINE-P is normally a face-boolean instantiator; see
650 `face-boolean-specifier-p'.
651 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
652 HOW-TO-ADD arguments."
653 (interactive (face-interactive "underline-p" "underlined"))
654 (set-face-property face 'underline underline-p locale tag-set how-to-add))
655
656 (defun face-strikethru-p (face &optional domain default no-fallback)
657 "Return whether the given face is strikethru-d (i.e. struck through).
658 See `face-property-instance' for the semantics of the DOMAIN argument."
659 (face-property-instance face 'strikethru domain default no-fallback))
660
661 (defun set-face-strikethru-p (face strikethru-p &optional locale tag-set
662 how-to-add)
663 "Change whether the given face is strikethru-d (i.e. struck through).
664 STRIKETHRU-P is normally a face-boolean instantiator; see
665 `face-boolean-specifier-p'.
666 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
667 HOW-TO-ADD arguments."
668 (interactive (face-interactive "strikethru-p" "strikethru-d"))
669 (set-face-property face 'strikethru strikethru-p locale tag-set how-to-add))
670
671 (defun face-highlight-p (face &optional domain default no-fallback)
672 "Return whether the given face is highlighted (TTY domains only).
673 See `face-property-instance' for the semantics of the DOMAIN argument."
674 (face-property-instance face 'highlight domain default no-fallback))
675
676 (defun set-face-highlight-p (face highlight-p &optional locale tag-set
677 how-to-add)
678 "Change whether the given face is highlighted (TTY locales only).
679 HIGHLIGHT-P is normally a face-boolean instantiator; see
680 `face-boolean-specifier-p'.
681 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
682 HOW-TO-ADD arguments."
683 (interactive (face-interactive "highlight-p" "highlighted"))
684 (set-face-property face 'highlight highlight-p locale tag-set how-to-add))
685
686 (defun face-dim-p (face &optional domain default no-fallback)
687 "Return whether the given face is dimmed (TTY domains only).
688 See `face-property-instance' for the semantics of the DOMAIN argument."
689 (face-property-instance face 'dim domain default no-fallback))
690
691 (defun set-face-dim-p (face dim-p &optional locale tag-set how-to-add)
692 "Change whether the given face is dimmed (TTY locales only).
693 DIM-P is normally a face-boolean instantiator; see
694 `face-boolean-specifier-p'.
695 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
696 HOW-TO-ADD arguments."
697 (interactive (face-interactive "dim-p" "dimmed"))
698 (set-face-property face 'dim dim-p locale tag-set how-to-add))
699
700 (defun face-blinking-p (face &optional domain default no-fallback)
701 "Return whether the given face is blinking (TTY domains only).
702 See `face-property-instance' for the semantics of the DOMAIN argument."
703 (face-property-instance face 'blinking domain default no-fallback))
704
705 (defun set-face-blinking-p (face blinking-p &optional locale tag-set
706 how-to-add)
707 "Change whether the given face is blinking (TTY locales only).
708 BLINKING-P is normally a face-boolean instantiator; see
709 `face-boolean-specifier-p'.
710 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
711 HOW-TO-ADD arguments."
712 (interactive (face-interactive "blinking-p" "blinking"))
713 (set-face-property face 'blinking blinking-p locale tag-set how-to-add))
714
715 (defun face-reverse-p (face &optional domain default no-fallback)
716 "Return whether the given face is reversed (TTY domains only).
717 See `face-property-instance' for the semantics of the DOMAIN argument."
718 (face-property-instance face 'reverse domain default no-fallback))
719
720 (defun set-face-reverse-p (face reverse-p &optional locale tag-set how-to-add)
721 "Change whether the given face is reversed (TTY locales only).
722 REVERSE-P is normally a face-boolean instantiator; see
723 `face-boolean-specifier-p'.
724 See `set-face-property' for the semantics of the LOCALE, TAG-SET, and
725 HOW-TO-ADD arguments."
726 (interactive (face-interactive "reverse-p" "reversed"))
727 (set-face-property face 'reverse reverse-p locale tag-set how-to-add))
728
729
730 (defun face-property-equal (face1 face2 prop domain)
731 (equal (face-property-instance face1 prop domain)
732 (face-property-instance face2 prop domain)))
733
734 (defun face-equal-loop (props face1 face2 domain)
735 (while (and props
736 (face-property-equal face1 face2 (car props) domain))
737 (setq props (cdr props)))
738 (null props))
739
740 (defun face-equal (face1 face2 &optional domain)
741 "True if the given faces will display in the same way.
742 See `face-property-instance' for the semantics of the DOMAIN argument."
743 (if (null domain) (setq domain (selected-window)))
744 (if (not (valid-specifier-domain-p domain))
745 (error "Invalid specifier domain"))
746 (let ((device (dfw-device domain))
747 (common-props '(foreground background font display-table underline))
748 (x-props '(background-pixmap strikethru))
749 (tty-props '(highlight dim blinking reverse)))
750
751 ;; First check the properties which are used in common between the
752 ;; x and tty devices. Then, check those properties specific to
753 ;; the particular device type.
754 (and (face-equal-loop common-props face1 face2 domain)
755 (cond ((eq 'tty (device-type device))
756 (face-equal-loop tty-props face1 face2 domain))
757 ((eq 'x (device-type device))
758 (face-equal-loop x-props face1 face2 domain))
759 (t t)))))
760
761 (defun face-differs-from-default-p (face &optional domain)
762 "True if the given face will display differently from the default face.
763 See `face-property-instance' for the semantics of the DOMAIN argument."
764 (not (face-equal face 'default domain)))
765
766
767 ;; This function is a terrible, disgusting hack!!!! Need to
768 ;; separate out the font elements as separate face properties!
769
770 ;; WE DEMAND LEXICAL SCOPING!!!
771 ;; WE DEMAND LEXICAL SCOPING!!!
772 ;; WE DEMAND LEXICAL SCOPING!!!
773 ;; WE DEMAND LEXICAL SCOPING!!!
774 ;; WE DEMAND LEXICAL SCOPING!!!
775 ;; WE DEMAND LEXICAL SCOPING!!!
776 ;; WE DEMAND LEXICAL SCOPING!!!
777 ;; WE DEMAND LEXICAL SCOPING!!!
778 ;; WE DEMAND LEXICAL SCOPING!!!
779 ;; WE DEMAND LEXICAL SCOPING!!!
780 ;; WE DEMAND LEXICAL SCOPING!!!
781 ;; WE DEMAND LEXICAL SCOPING!!!
782 ;; WE DEMAND LEXICAL SCOPING!!!
783 ;; WE DEMAND LEXICAL SCOPING!!!
784 ;; WE DEMAND LEXICAL SCOPING!!!
785 (defun frob-face-property (face property func &optional locale)
786 "Change the specifier for FACE's PROPERTY according to FUNC, in LOCALE.
787 This function is ugly and messy and is primarily used as an internal
788 helper function for `make-face-bold' et al., so you probably don't
789 want to use it or read the rest of the documentation. But if you do ...
790
791 FUNC should be a function of two arguments (an instance and a device)
792 that returns a modified name that is valid for the given device.
793 If LOCALE specifies a valid domain (i.e. a window, frame, or device),
794 this function instantiates the specifier over that domain, applies FUNC
795 to the resulting instance, and adds the result back as an instantiator
796 for that locale. Otherwise, LOCALE should be a locale, locale type, or
797 'all (defaults to 'all if omitted). For each specification thusly
798 included: if the locale given is a valid domain, FUNC will be
799 iterated over all valid instantiators for the device of the domain
800 until a non-nil result is found (if there is no such result, the
801 first valid instantiator is used), and that result substituted for
802 the specification; otherwise, the process just outlined is
803 iterated over each existing device and the concatenated results
804 substituted for the specification."
805 (let ((sp (face-property face property)))
806 (if (valid-specifier-domain-p locale)
807 ;; this is easy.
808 (let* ((inst (face-property-instance face property locale))
809 (name (and inst (funcall func inst (dfw-device locale)))))
810 (when name
811 (add-spec-to-specifier sp name locale)))
812 ;; otherwise, map over all specifications ...
813 ;; but first, some further kludging:
814 ;; (1) if we're frobbing the global property, make sure
815 ;; that something is there (copy from the default face,
816 ;; if necessary). Otherwise, something like
817 ;; (make-face-larger 'modeline)
818 ;; won't do anything at all if the modeline simply
819 ;; inherits its font from 'default.
820 ;; (2) if we're frobbing a particular locale, nothing would
821 ;; happen if that locale has no instantiators. So signal
822 ;; an error to indicate this.
823 (if (and (or (eq locale 'global) (eq locale 'all) (not locale))
824 (not (face-property face property 'global)))
825 (copy-specifier (face-property 'default property)
826 (face-property face property)
827 'global))
828 (if (and (valid-specifier-locale-p locale)
829 (not (face-property face property locale)))
830 (error "Property must have a specification in locale %S" locale))
831 (map-specifier
832 sp
833 (lambda (sp locale inst-list func)
834 (let* ((device (dfw-device locale))
835 ;; if a device can be derived from the locale,
836 ;; call frob-face-property-1 for that device.
837 ;; Otherwise map frob-face-property-1 over each device.
838 (result
839 (if device
840 (list (frob-face-property-1 sp device inst-list func))
841 (mapcar (lambda (device)
842 (frob-face-property-1 sp device
843 inst-list func))
844 (device-list))))
845 new-result)
846 ;; remove duplicates and nils from the obtained list of
847 ;; instantiators.
848 (mapcar (lambda (arg)
849 (when (and arg (not (member arg new-result)))
850 (setq new-result (cons arg new-result))))
851 result)
852 ;; add back in.
853 (add-spec-list-to-specifier sp (list (cons locale new-result)))
854 ;; tell map-specifier to keep going.
855 nil))
856 locale
857 func))))
858
859 (defun frob-face-property-1 (sp device inst-list func)
860 (let
861 (first-valid result)
862 (while (and inst-list (not result))
863 (let* ((inst-pair (car inst-list))
864 (tag-set (car inst-pair))
865 (sp-inst (specifier-instance-from-inst-list
866 sp device (list inst-pair))))
867 (if sp-inst
868 (progn
869 (if (not first-valid)
870 (setq first-valid inst-pair))
871 (setq result (funcall func sp-inst device))
872 (if result
873 (setq result (cons tag-set result))))))
874 (setq inst-list (cdr inst-list)))
875 (or result first-valid)))
876
877 (defun frob-face-font-2 (face locale unfrobbed-face frobbed-face
878 tty-thunk x-thunk standard-face-mapping)
879 ;; another kludge to make things more intuitive. If we're
880 ;; inheriting from a standard face in this locale, frob the
881 ;; inheritance as appropriate. Else, if, after the first X frobbing
882 ;; pass, the face hasn't changed and still looks like the standard
883 ;; unfrobbed face (e.g. 'default), make it inherit from the standard
884 ;; frobbed face (e.g. 'bold). Regardless of things, do the TTY
885 ;; frobbing.
886
887 ;; yuck -- The LOCALE argument to make-face-bold is not actually a locale,
888 ;; but is a "locale, locale-type, or nil for all". So ... do our extra
889 ;; frobbing only if it's actually a locale; or for nil, do the frobbing
890 ;; on 'global. This specifier stuff needs some rethinking.
891 (let* ((the-locale (cond ((null locale) 'global)
892 ((valid-specifier-locale-p locale) locale)
893 (t nil)))
894 (specs (and the-locale (face-font face the-locale nil t)))
895 (change-it (and specs (cdr (assoc specs standard-face-mapping)))))
896 (if (and change-it
897 (not (memq (face-name (find-face face))
898 '(default bold italic bold-italic))))
899 (progn
900 (or (equal change-it t)
901 (set-face-property face 'font change-it the-locale))
902 (funcall tty-thunk))
903 (let* ((domain (cond ((null the-locale) nil)
904 ((valid-specifier-domain-p the-locale) the-locale)
905 ;; OK, this next one is truly a kludge, but
906 ;; it results in more intuitive behavior most
907 ;; of the time. (really!)
908 ((or (eq the-locale 'global) (eq the-locale 'all))
909 (selected-device))
910 (t nil)))
911 (inst (and domain (face-property-instance face 'font domain))))
912 (funcall tty-thunk)
913 (funcall x-thunk)
914 ;; If it's reasonable to do the inherit-from-standard-face trick,
915 ;; and it's called for, then do it now.
916 (or (null domain)
917 (not (equal inst (face-property-instance face 'font domain)))
918 ;; don't do it for standard faces, or you'll get inheritance loops.
919 ;; #### This makes XEmacs seg fault! fix this bug.
920 (memq (face-name (find-face face))
921 '(default bold italic bold-italic))
922 (not (equal (face-property-instance face 'font domain)
923 (face-property-instance unfrobbed-face 'font domain)))
924 (set-face-property face 'font (vector frobbed-face)
925 the-locale))))))
926
927 (defun make-face-bold (face &optional locale)
928 "Make the face bold, if possible.
929 This will attempt to make the font bold for X locales and will set the
930 highlight flag for TTY locales.
931
932 If LOCALE is nil, omitted, or `all', this will attempt to frob all
933 font specifications for FACE to make them appear bold. Similarly, if
934 LOCALE is a locale type, this frobs all font specifications for locales
935 of that type. If LOCALE is a particular locale, what happens depends on
936 what sort of locale is given. If you gave a device, frame, or window,
937 then it's always possible to determine what the font actually will be,
938 so this is determined and the resulting font is frobbed and added back as a
939 specification for this locale. If LOCALE is a buffer, however, you can't
940 determine what the font will actually be unless there's actually a
941 specification given for that particular buffer (otherwise, it depends
942 on what window and frame the buffer appears in, and might not even be
943 well-defined if the buffer appears multiple times in different places);
944 therefore you will get an error unless there's a specification for the
945 buffer.
946
947 Finally, in some cases (specifically, when LOCALE is not a locale type),
948 if the frobbing didn't actually make the font look any different
949 \(this happens, for example, if your font specification is already bold
950 or has no bold equivalent), and currently looks like the font of the
951 'default face, it is set to inherit from the 'bold face. This is kludgy
952 but it makes `make-face-bold' have more intuitive behavior in many
953 circumstances."
954 (interactive (list (read-face-name "Make which face bold: ")))
955 (frob-face-font-2
956 face locale 'default 'bold
957 (lambda ()
958 ;; handle TTY specific entries
959 (when (featurep 'tty)
960 (set-face-highlight-p face t locale 'tty)))
961 (lambda ()
962 ;; handle X specific entries
963 (cond ((featurep 'x)
964 (frob-face-property face 'font 'x-make-font-bold locale))
965 ((featurep 'w32)
966 (frob-face-property face 'font 'w32-make-font-bold locale))
967 ))
968 '(([default] . [bold])
969 ([bold] . t)
970 ([italic] . [bold-italic])
971 ([bold-italic] . t))))
972
973 (defun make-face-italic (face &optional locale)
974 "Make the face italic, if possible.
975 This will attempt to make the font italic for X locales and will set
976 the underline flag for TTY locales.
977 See `make-face-bold' for the semantics of the LOCALE argument and
978 for more specifics on exactly how this function works."
979 (interactive (list (read-face-name "Make which face italic: ")))
980 (frob-face-font-2
981 face locale 'default 'italic
982 (lambda ()
983 ;; handle TTY specific entries
984 (when (featurep 'tty)
985 (set-face-underline-p face t locale 'tty)))
986 (lambda ()
987 ;; handle X specific entries
988 (cond ((featurep 'x)
989 (frob-face-property face 'font 'x-make-font-italic locale))
990 ((featurep 'w32)
991 (frob-face-property face 'font 'w32-make-font-italic locale))
992 ))
993 '(([default] . [italic])
994 ([bold] . [bold-italic])
995 ([italic] . t)
996 ([bold-italic] . t))))
997
998 (defun make-face-bold-italic (face &optional locale)
999 "Make the face bold and italic, if possible.
1000 This will attempt to make the font bold-italic for X locales and will
1001 set the highlight and underline flags for TTY locales.
1002 See `make-face-bold' for the semantics of the LOCALE argument and
1003 for more specifics on exactly how this function works."
1004 (interactive (list (read-face-name "Make which face bold-italic: ")))
1005 (frob-face-font-2
1006 face locale 'default 'bold-italic
1007 (lambda ()
1008 ;; handle TTY specific entries
1009 (when (featurep 'tty)
1010 (set-face-highlight-p face t locale 'tty)
1011 (set-face-underline-p face t locale 'tty)))
1012 (lambda ()
1013 ;; handle X specific entries
1014 (cond ((featurep 'x)
1015 (frob-face-property face 'font 'x-make-font-bold-italic locale))
1016 ((featurep 'w32)
1017 (frob-face-property face 'font 'w32-make-font-bold-italic locale))
1018 ))
1019 '(([default] . [italic])
1020 ([bold] . [bold-italic])
1021 ([italic] . [bold-italic])
1022 ([bold-italic] . t))))
1023
1024 (defun make-face-unbold (face &optional locale)
1025 "Make the face non-bold, if possible.
1026 This will attempt to make the font non-bold for X locales and will
1027 unset the highlight flag for TTY locales.
1028 See `make-face-bold' for the semantics of the LOCALE argument and
1029 for more specifics on exactly how this function works."
1030 (interactive (list (read-face-name "Make which face non-bold: ")))
1031 (frob-face-font-2
1032 face locale 'bold 'default
1033 (lambda ()
1034 ;; handle TTY specific entries
1035 (when (featurep 'tty)
1036 (set-face-highlight-p face nil locale 'tty)))
1037 (lambda ()
1038 ;; handle X specific entries
1039 (cond ((featurep 'x)
1040 (frob-face-property face 'font 'x-make-font-unbold locale))
1041 ((featurep 'w32)
1042 (frob-face-property face 'font 'w32-make-font-unbold locale))
1043 ))
1044 '(([default] . t)
1045 ([bold] . [default])
1046 ([italic] . t)
1047 ([bold-italic] . [italic]))))
1048
1049 (defun make-face-unitalic (face &optional locale)
1050 "Make the face non-italic, if possible.
1051 This will attempt to make the font non-italic for X locales and will
1052 unset the underline flag for TTY locales.
1053 See `make-face-bold' for the semantics of the LOCALE argument and
1054 for more specifics on exactly how this function works."
1055 (interactive (list (read-face-name "Make which face non-italic: ")))
1056 (frob-face-font-2
1057 face locale 'italic 'default
1058 (lambda ()
1059 ;; handle TTY specific entries
1060 (when (featurep 'tty)
1061 (set-face-underline-p face nil locale 'tty)))
1062 (lambda ()
1063 ;; handle X specific entries
1064 (cond ((featurep 'x)
1065 (frob-face-property face 'font 'x-make-font-unitalic locale))
1066 ((featurep 'w32)
1067 (frob-face-property face 'font 'w32-make-font-unitalic locale))
1068 ))
1069 '(([default] . t)
1070 ([bold] . t)
1071 ([italic] . [default])
1072 ([bold-italic] . [bold]))))
1073
1074
1075 ;; Why do the following two functions lose so badly in so many
1076 ;; circumstances?
1077
1078 (defun make-face-smaller (face &optional locale)
1079 "Make the font of the given face be smaller, if possible.
1080 LOCALE works as in `make-face-bold' et al., but the ``inheriting-
1081 from-the-bold-face'' operations described there are not done
1082 because they don't make sense in this context."
1083 (interactive (list (read-face-name "Shrink which face: ")))
1084 ;; handle X specific entries
1085 (cond ((featurep 'x)
1086 (frob-face-property face 'font 'x-find-smaller-font locale))
1087 ((featurep 'w32)
1088 (frob-face-property face 'font 'w32-find-smaller-font locale))))
1089
1090 (defun make-face-larger (face &optional locale)
1091 "Make the font of the given face be larger, if possible.
1092 See `make-face-smaller' for the semantics of the LOCALE argument."
1093 (interactive (list (read-face-name "Enlarge which face: ")))
1094 ;; handle X specific entries
1095 (cond ((featurep 'x)
1096 (frob-face-property face 'font 'x-find-larger-font locale))
1097 ((featurep 'w32)
1098 (frob-face-property face 'font 'w32-find-larger-font locale))))
1099
1100 (defun invert-face (face &optional locale)
1101 "Swap the foreground and background colors of the face."
1102 (interactive (list (read-face-name "Invert face: ")))
1103 (if (valid-specifier-domain-p locale)
1104 (let ((foreface (face-foreground-instance face locale)))
1105 (set-face-foreground face (face-background-instance face locale)
1106 locale)
1107 (set-face-background face foreface locale))
1108 (let ((forespec (copy-specifier (face-foreground face) nil locale)))
1109 (copy-specifier (face-background face) (face-foreground face) locale)
1110 (copy-specifier forespec (face-background face) locale))))
1111
1112
1113 ;;; Convenience functions
1114
1115 (defun face-ascent (face &optional domain charset)
1116 "Return the ascent of a face.
1117 See `face-property-instance' for the semantics of the DOMAIN argument."
1118 (font-ascent (face-font face) domain charset))
1119
1120 (defun face-descent (face &optional domain charset)
1121 "Return the descent of a face.
1122 See `face-property-instance' for the semantics of the DOMAIN argument."
1123 (font-descent (face-font face) domain charset))
1124
1125 (defun face-width (face &optional domain charset)
1126 "Return the width of a face.
1127 See `face-property-instance' for the semantics of the DOMAIN argument."
1128 (font-width (face-font face) domain charset))
1129
1130 (defun face-height (face &optional domain charset)
1131 "Return the height of a face.
1132 See `face-property-instance' for the semantics of the DOMAIN argument."
1133 (+ (face-ascent face domain charset) (face-descent face domain charset)))
1134
1135 (defun face-proportional-p (face &optional domain charset)
1136 "Return whether FACE is proportional.
1137 See `face-property-instance' for the semantics of the DOMAIN argument."
1138 (font-proportional-p (face-font face) domain charset))
1139
1140
1141 ;; Functions that used to be in cus-face.el, but logically go here.
1142
1143 (defcustom frame-background-mode nil
1144 "*The brightness of the background.
1145 Set this to the symbol dark if your background color is dark, light if
1146 your background is light, or nil (default) if you want Emacs to
1147 examine the brightness for you."
1148 :group 'faces
1149 :type '(choice (choice-item dark)
1150 (choice-item light)
1151 (choice-item :tag "Auto" nil)))
1152
1153 ;; The old variable that many people still have in .emacs files.
1154 (define-obsolete-variable-alias 'custom-background-mode
1155 'frame-background-mode)
1156
1157 (defun get-frame-background-mode (frame)
1158 "Detect background mode for FRAME."
1159 (let* ((color-instance (face-background-instance 'default frame))
1160 (mode (condition-case nil
1161 (if (< (apply '+ (color-instance-rgb-components
1162 color-instance)) 65536)
1163 'dark 'light)
1164 ;; Here, we get an error on a TTY. As we don't have
1165 ;; a good way of detecting whether a TTY is light or
1166 ;; dark, we'll guess it's dark.
1167 (error 'dark))))
1168 (set-frame-property frame 'background-mode mode)
1169 mode))
1170
1171 (defun extract-custom-frame-properties (frame)
1172 "Return a plist with the frame properties of FRAME used by custom."
1173 (list 'type (or (frame-property frame 'display-type)
1174 (device-type (frame-device frame)))
1175 'class (device-class (frame-device frame))
1176 'background (or frame-background-mode
1177 (frame-property frame 'background-mode)
1178 (get-frame-background-mode frame))))
1179
1180 (defcustom init-face-from-resources t
1181 "If non nil, attempt to initialize faces from the resource database."
1182 :group 'faces
1183 :type 'boolean)
1184
1185 ;; Old name, used by custom. Also, FSFmacs name.
1186 (defvaralias 'initialize-face-resources 'init-face-from-resources)
1187
1188 (defun face-spec-set (face spec &optional frame)
1189 "Set FACE's face attributes according to the first matching entry in SPEC.
1190 If optional FRAME is non-nil, set it for that frame only.
1191 If it is nil, then apply SPEC to each frame individually.
1192 See `defface' for information about SPEC."
1193 (if frame
1194 (progn
1195 (reset-face face frame)
1196 (face-display-set face spec frame)
1197 (init-face-from-resources face frame))
1198 (let ((frames (relevant-custom-frames)))
1199 (reset-face face)
1200 (face-display-set face spec)
1201 (while frames
1202 (face-display-set face spec (car frames))
1203 (pop frames))
1204 (init-face-from-resources face))))
1205
1206 (defun face-display-set (face spec &optional frame)
1207 "Set FACE to the attributes to the first matching entry in SPEC.
1208 Iff optional FRAME is non-nil, set it for that frame only.
1209 See `defface' for information about SPEC."
1210 (while spec
1211 (let ((display (caar spec))
1212 (atts (cadar spec)))
1213 (pop spec)
1214 (when (face-spec-set-match-display display frame)
1215 ;; Avoid creating frame local duplicates of the global face.
1216 (unless (and frame (eq display (get face 'custom-face-display)))
1217 (apply 'face-custom-attributes-set face frame atts))
1218 (unless frame
1219 (put face 'custom-face-display display))
1220 (setq spec nil)))))
1221
1222 (defvar default-custom-frame-properties nil
1223 "The frame properties used for the global faces.
1224 Frames not matching these propertiess should have frame local faces.
1225 The value should be nil, if uninitialized, or a plist otherwise.
1226 See `defface' for a list of valid keys and values for the plist.")
1227
1228 (defun get-custom-frame-properties (&optional frame)
1229 "Return a plist with the frame properties of FRAME used by custom.
1230 If FRAME is nil, return the default frame properties."
1231 (cond (frame
1232 ;; Try to get from cache.
1233 (let ((cache (frame-property frame 'custom-properties)))
1234 (unless cache
1235 ;; Oh well, get it then.
1236 (setq cache (extract-custom-frame-properties frame))
1237 ;; and cache it...
1238 (set-frame-property frame 'custom-properties cache))
1239 cache))
1240 (default-custom-frame-properties)
1241 (t
1242 (setq default-custom-frame-properties
1243 (extract-custom-frame-properties (selected-frame))))))
1244
1245 (defun face-spec-set-match-display (display frame)
1246 "Non-nil iff DISPLAY matches FRAME.
1247 DISPLAY is part of a spec such as can be used in `defface'.
1248 If FRAME is nil, the current FRAME is used."
1249 (if (eq display t)
1250 t
1251 (let* ((props (get-custom-frame-properties frame))
1252 (type (plist-get props 'type))
1253 (class (plist-get props 'class))
1254 (background (plist-get props 'background))
1255 (match t)
1256 (entries display)
1257 entry req options)
1258 (while (and entries match)
1259 (setq entry (car entries)
1260 entries (cdr entries)
1261 req (car entry)
1262 options (cdr entry)
1263 match (case req
1264 (type (memq type options))
1265 (class (memq class options))
1266 (background (memq background options))
1267 (t (warn "Unknown req `%S' with options `%S'"
1268 req options)
1269 nil))))
1270 match)))
1271
1272 (defun relevant-custom-frames ()
1273 "List of frames whose custom properties differ from the default."
1274 (let ((relevant nil)
1275 (default (get-custom-frame-properties))
1276 (frames (frame-list))
1277 frame)
1278 (while frames
1279 (setq frame (car frames)
1280 frames (cdr frames))
1281 (unless (equal default (get-custom-frame-properties frame))
1282 (push frame relevant)))
1283 relevant))
1284
1285 (defun initialize-custom-faces (&optional frame)
1286 "Initialize all custom faces for FRAME.
1287 If FRAME is nil or omitted, initialize them for all frames."
1288 (mapc (lambda (symbol)
1289 (let ((spec (or (get symbol 'saved-face)
1290 (get symbol 'face-defface-spec))))
1291 (when spec
1292 ;; No need to init-face-from-resources -- code in
1293 ;; `init-frame-faces' does it already.
1294 (face-display-set symbol spec frame))))
1295 (face-list)))
1296
1297 (defun custom-initialize-frame (frame)
1298 "Initialize frame-local custom faces for FRAME if necessary."
1299 (unless (equal (get-custom-frame-properties)
1300 (get-custom-frame-properties frame))
1301 (initialize-custom-faces frame)))
1302
1303
1304 (defun make-empty-face (name &optional doc-string temporary)
1305 "Like `make-face', but doesn't query the resource database."
1306 (let ((init-face-from-resources nil))
1307 (make-face name doc-string temporary)))
1308
1309 (defun init-face-from-resources (face &optional locale)
1310 "Initialize FACE from the resource database.
1311 If LOCALE is specified, it should be a frame, device, or 'global, and
1312 the face will be resourced over that locale. Otherwise, the face will
1313 be resourced over all possible locales (i.e. all frames, all devices,
1314 and 'global)."
1315 (cond ((null init-face-from-resources)
1316 ;; Do nothing.
1317 )
1318 ((not locale)
1319 ;; Global, set for all frames.
1320 (progn
1321 (init-face-from-resources face 'global)
1322 (let ((devices (device-list)))
1323 (while devices
1324 (init-face-from-resources face (car devices))
1325 (setq devices (cdr devices))))
1326 (let ((frames (frame-list)))
1327 (while frames
1328 (init-face-from-resources face (car frames))
1329 (setq frames (cdr frames))))))
1330 (t
1331 ;; Specific.
1332 (let ((devtype (cond ((devicep locale) (device-type locale))
1333 ((framep locale) (frame-type locale))
1334 (t nil))))
1335 (cond ((or (and (not devtype) (featurep 'x)) (eq 'x devtype))
1336 (x-init-face-from-resources face locale))
1337 ((or (not devtype) (eq 'tty devtype))
1338 ;; Nothing to do for TTYs?
1339 ))))))
1340
1341 (defun init-device-faces (device)
1342 ;; First, add any device-local face resources.
1343 (when init-face-from-resources
1344 (loop for face in (face-list) do
1345 (init-face-from-resources face device))
1346 ;; Then do any device-specific initialization.
1347 (cond ((eq 'x (device-type device))
1348 (x-init-device-faces device))
1349 ((eq 'w32 (device-type device))
1350 (w32-init-device-faces device))
1351 ;; Nothing to do for TTYs?
1352 )
1353 (init-other-random-faces device)))
1354
1355 (defun init-frame-faces (frame)
1356 (when init-face-from-resources
1357 ;; First, add any frame-local face resources.
1358 (loop for face in (face-list) do
1359 (init-face-from-resources face frame))
1360 ;; Then do any frame-specific initialization.
1361 (cond ((eq 'x (frame-type frame))
1362 (x-init-frame-faces frame))
1363 ((eq 'w32 (frame-type frame))
1364 (w32-init-frame-faces frame))
1365 ;; Is there anything which should be done for TTY's?
1366 )))
1367
1368 ;; #### This is somewhat X-specific, and is called when the first
1369 ;; X device is created (even if there were TTY devices created
1370 ;; beforehand). The concept of resources has not been generalized
1371 ;; outside of X-specificness, so we have to live with this
1372 ;; breach of device-independence.
1373
1374 (defun init-global-faces ()
1375 ;; Look for global face resources.
1376 (loop for face in (face-list) do
1377 (init-face-from-resources face 'global))
1378 ;; Further X frobbing.
1379 (x-init-global-faces)
1380 ;; for bold and the like, make the global specification be bold etc.
1381 ;; if the user didn't already specify a value. These will also be
1382 ;; frobbed further in init-other-random-faces.
1383 (unless (face-font 'bold 'global)
1384 (make-face-bold 'bold 'global))
1385 ;;
1386 (unless (face-font 'italic 'global)
1387 (make-face-italic 'italic 'global))
1388 ;;
1389 (unless (face-font 'bold-italic 'global)
1390 (make-face-bold-italic 'bold-italic 'global)
1391 (unless (face-font 'bold-italic 'global)
1392 (copy-face 'bold 'bold-italic)
1393 (make-face-italic 'bold-italic)))
1394
1395 (when (face-equal 'bold 'bold-italic)
1396 (copy-face 'italic 'bold-italic)
1397 (make-face-bold 'bold-italic))
1398 ;;
1399 ;; Nothing more to be done for X or TTY's?
1400 )
1401
1402
1403 ;; These warnings are there for a reason. Just specify your fonts
1404 ;; correctly. Deal with it. Additionally, one can use
1405 ;; `log-warning-minimum-level' instead of this.
1406 ;(defvar inhibit-font-complaints nil
1407 ; "Whether to suppress complaints about incomplete sets of fonts.")
1408
1409 (defun face-complain-about-font (face device)
1410 (if (symbolp face) (setq face (symbol-name face)))
1411 ;; (if (not inhibit-font-complaints)
1412 (display-warning
1413 'font
1414 (let ((default-name (face-font-name 'default device)))
1415 (format "%s: couldn't deduce %s %s version of the font
1416 %S.
1417
1418 Please specify X resources to make the %s face
1419 visually distinguishable from the default face.
1420 For example, you could add one of the following to $HOME/Emacs:
1421
1422 Emacs.%s.attributeFont: -dt-*-medium-i-*
1423 or
1424 Emacs.%s.attributeForeground: hotpink\n"
1425 invocation-name
1426 (if (string-match "\\`[aeiouAEIOU]" face) "an" "a")
1427 face
1428 default-name
1429 face
1430 face
1431 face
1432 ))))
1433
1434
1435 ;; #### This is quite a mess. We should use the custom mechanism for
1436 ;; most of this stuff. Currently we don't do it, because Custom
1437 ;; doesn't use specifiers (yet.) FSF does it the Right Way.
1438
1439 ;; For instance, the definition of `bold' should be something like
1440 ;; (defface bold ((t (:bold t))) "Bold text.") -- and `:bold t' should
1441 ;; make sure that everything works properly.
1442
1443 (defun init-other-random-faces (device)
1444 "Initializes the colors and fonts of the bold, italic, bold-italic,
1445 zmacs-region, list-mode-item-selected, highlight, primary-selection,
1446 secondary-selection, and isearch faces when each device is created. If
1447 you want to add code to do stuff like this, use the create-device-hook."
1448
1449 ;; try to make 'bold look different from the default on this device.
1450 ;; If that doesn't work at all, then issue a warning.
1451 (unless (face-differs-from-default-p 'bold device)
1452 (make-face-bold 'bold device)
1453 (unless (face-differs-from-default-p 'bold device)
1454 (make-face-unbold 'bold device)
1455 (unless (face-differs-from-default-p 'bold device)
1456 ;; the luser specified one of the bogus font names
1457 (face-complain-about-font 'bold device))))
1458
1459 ;; Similar for italic.
1460 ;; It's unreasonable to expect to be able to make a font italic all
1461 ;; the time. For many languages, italic is an alien concept.
1462 ;; Basically, because italic is not a globally meaningful concept,
1463 ;; the use of the italic face should really be oboleted.
1464
1465 ;; I disagree with above. In many languages, the concept of capital
1466 ;; letters is just as alien, and yet we use them. Italic is here to
1467 ;; stay. -hniksic
1468
1469 ;; In a Solaris Japanese environment, there just aren't any italic
1470 ;; fonts - period. CDE recognizes this reality, and fonts
1471 ;; -dt-interface user-medium-r-normal-*-*-*-*-*-*-*-*-* don't come
1472 ;; in italic versions. So we first try to make the font bold before
1473 ;; complaining.
1474 (unless (face-differs-from-default-p 'italic device)
1475 (make-face-italic 'italic device)
1476 (unless (face-differs-from-default-p 'italic device)
1477 (make-face-bold 'italic device)
1478 (unless (face-differs-from-default-p 'italic device)
1479 (face-complain-about-font 'italic device))))
1480
1481 ;; similar for bold-italic.
1482 (unless (face-differs-from-default-p 'bold-italic device)
1483 (make-face-bold-italic 'bold-italic device)
1484 ;; if we couldn't get a bold-italic version, try just bold.
1485 (unless (face-differs-from-default-p 'bold-italic device)
1486 (make-face-bold 'bold-italic device)
1487 ;; if we couldn't get bold or bold-italic, then that's probably because
1488 ;; the default font is bold, so make the `bold-italic' face be unbold.
1489 (unless (face-differs-from-default-p 'bold-italic device)
1490 (make-face-unbold 'bold-italic device)
1491 (make-face-italic 'bold-italic device)
1492 (unless (face-differs-from-default-p 'bold-italic device)
1493 ;; if that didn't work, try plain italic
1494 ;; (can this ever happen? what the hell.)
1495 (make-face-italic 'bold-italic device)
1496 (unless (face-differs-from-default-p 'bold-italic device)
1497 ;; then bitch and moan.
1498 (face-complain-about-font 'bold-italic device))))))
1499
1500 ;; Set the text-cursor colors unless already specified.
1501 (when (and (not (eq 'tty (device-type device)))
1502 (not (face-background 'text-cursor 'global))
1503 (face-property-equal 'text-cursor 'default 'background device))
1504 (set-face-background 'text-cursor [default foreground] 'global
1505 nil 'append))
1506 (when (and (not (eq 'tty (device-type device)))
1507 (not (face-foreground 'text-cursor 'global))
1508 (face-property-equal 'text-cursor 'default 'foreground device))
1509 (set-face-foreground 'text-cursor [default background] 'global
1510 nil 'append))
1511
1512 ;; Set the secondary-selection color unless already specified.
1513 (unless (or (face-differs-from-default-p 'highlight device)
1514 (face-background 'highlight 'global))
1515 ;; some older servers don't recognize "darkseagreen2"
1516 (set-face-background 'highlight
1517 '((color . "darkseagreen2")
1518 (color . "green"))
1519 'global nil 'append)
1520 (set-face-background 'highlight "gray53" 'global 'grayscale 'append))
1521 (unless (or (face-differs-from-default-p 'highlight device)
1522 (face-background-pixmap 'highlight 'global))
1523 (set-face-background-pixmap 'highlight [nothing] 'global 'color 'append)
1524 (set-face-background-pixmap 'highlight [nothing] 'global 'grayscale 'append)
1525 (set-face-background-pixmap 'highlight "gray1" 'global 'mono 'append))
1526 ;; if the highlight face isn't distinguished on this device,
1527 ;; at least try inverting it.
1528 (unless (face-differs-from-default-p 'highlight device)
1529 (invert-face 'highlight device))
1530
1531 ;; first time through, set the zmacs-region color if it's not already
1532 ;; specified.
1533 (unless (or (face-differs-from-default-p 'zmacs-region device)
1534 (face-background 'zmacs-region 'global))
1535 (set-face-background 'zmacs-region "gray65" 'global 'color)
1536 (set-face-background 'zmacs-region "gray65" 'global 'grayscale))
1537 (unless (or (face-differs-from-default-p 'zmacs-region device)
1538 (face-background-pixmap 'zmacs-region 'global))
1539 (set-face-background-pixmap 'zmacs-region [nothing] 'global 'color)
1540 (set-face-background-pixmap 'zmacs-region [nothing] 'global 'grayscale)
1541 (set-face-background-pixmap 'zmacs-region "gray3" 'global 'mono))
1542 ;; if the zmacs-region face isn't distinguished on this device,
1543 ;; at least try inverting it.
1544 (unless (face-differs-from-default-p 'zmacs-region device)
1545 (invert-face 'zmacs-region device))
1546
1547 ;; first time through, set the list-mode-item-selected color if it's
1548 ;; not already specified.
1549 (unless (or (face-differs-from-default-p 'list-mode-item-selected device)
1550 (face-background 'list-mode-item-selected 'global))
1551 (set-face-background 'list-mode-item-selected "gray68" 'global 'color)
1552 (set-face-background 'list-mode-item-selected "gray68" 'global 'grayscale)
1553 (if (featurep 'x)
1554 (unless (face-foreground 'list-mode-item-selected 'global)
1555 (set-face-background 'list-mode-item-selected
1556 [default foreground] 'global '(mono x))
1557 (set-face-foreground 'list-mode-item-selected
1558 [default background] 'global '(mono x)))))
1559
1560 ;; if the list-mode-item-selected face isn't distinguished on this device,
1561 ;; at least try inverting it.
1562 (unless (face-differs-from-default-p 'list-mode-item-selected device)
1563 (invert-face 'list-mode-item-selected device))
1564
1565 ;; Set the primary-selection color unless already specified.
1566 (unless (or (face-differs-from-default-p 'primary-selection device)
1567 (face-background 'primary-selection 'global))
1568 (set-face-background 'primary-selection "gray65" 'global 'color)
1569 (set-face-background 'primary-selection "gray65" 'global 'grayscale))
1570 (unless (or (face-differs-from-default-p 'secondary-selection device)
1571 (face-background-pixmap 'primary-selection 'global))
1572 (set-face-background-pixmap 'primary-selection "gray3" 'global 'mono))
1573 ;; If the primary-selection face isn't distinguished on this device,
1574 ;; at least try inverting it.
1575 (unless (face-differs-from-default-p 'primary-selection device)
1576 (invert-face 'primary-selection device))
1577
1578 ;; Set the secondary-selection color unless already specified.
1579 (unless (or (face-differs-from-default-p 'secondary-selection device)
1580 (face-background 'secondary-selection 'global))
1581 (set-face-background 'secondary-selection
1582 '((color . "paleturquoise")
1583 (color . "green"))
1584 'global)
1585 (set-face-background 'secondary-selection "gray53" 'global
1586 'grayscale))
1587 (unless (or (face-differs-from-default-p 'secondary-selection device)
1588 (face-background-pixmap 'secondary-selection 'global))
1589 (set-face-background-pixmap 'secondary-selection "gray1" 'global 'mono))
1590 ;; If the secondary-selection face isn't distinguished on this device,
1591 ;; at least try inverting it.
1592 (unless (face-differs-from-default-p 'secondary-selection device)
1593 (invert-face 'secondary-selection device))
1594
1595 ;; Set the isearch color if unless already specified.
1596 (unless (or (face-differs-from-default-p 'isearch device)
1597 (face-background 'isearch 'global))
1598 ;; TTY's and some older X servers don't recognize "paleturquoise"
1599 (set-face-background 'isearch
1600 '((color . "paleturquoise")
1601 (color . "green"))
1602 'global))
1603 ;; if the isearch face isn't distinguished (e.g. we're not on a color
1604 ;; display), at least try making it bold.
1605 (unless (face-differs-from-default-p 'isearch device)
1606 (set-face-font 'isearch [bold]))
1607 )
1608
1609 ;; New function with 20.1, suggested by Per Abrahamsen, coded by Kyle Jones.
1610 (defun set-face-stipple (face pixmap &optional frame)
1611 "Change the stipple pixmap of face FACE to PIXMAP.
1612 This is an Emacs compatibility function; consider using
1613 set-face-background-pixmap instead.
1614
1615 PIXMAP should be a string, the name of a file of pixmap data.
1616 The directories listed in the `x-bitmap-file-path' variable are searched.
1617 Any kind of image file for which XEmacs has builtin support can be used.
1618
1619 Alternatively, PIXMAP may be a list of the form (WIDTH HEIGHT
1620 DATA) where WIDTH and HEIGHT are the size in pixels, and DATA is
1621 a string, containing the raw bits of the bitmap. XBM data is
1622 expected in this case, other types of image data will not work.
1623
1624 If the optional FRAME argument is provided, change only
1625 in that frame; otherwise change each frame."
1626 (while (not (find-face face))
1627 (setq face (signal 'wrong-type-argument (list 'facep face))))
1628 (while (cond ((stringp pixmap)
1629 (unless (file-readable-p pixmap)
1630 (setq pixmap `[xbm :file ,pixmap]))
1631 nil)
1632 ((and (consp pixmap) (= (length pixmap) 3))
1633 (setq pixmap `[xbm :data ,pixmap])
1634 nil)
1635 (t t))
1636 (setq pixmap (signal 'wrong-type-argument
1637 (list 'stipple-pixmap-p pixmap))))
1638 (while (and frame (not (framep frame)))
1639 (setq frame (signal 'wrong-type-argument (list 'framep frame))))
1640 (set-face-background-pixmap face pixmap frame))
1641
1642
1643 ;; Create the remaining standard faces now. This way, packages that we dump
1644 ;; can reference these faces as parents.
1645 ;;
1646 ;; The default, modeline, left-margin, right-margin, text-cursor,
1647 ;; and pointer faces are created in C.
1648
1649 (make-face 'bold "Bold text.")
1650 (make-face 'italic "Italic text.")
1651 (make-face 'bold-italic "Bold-italic text.")
1652 (make-face 'underline "Underlined text.")
1653 (or (face-differs-from-default-p 'underline)
1654 (set-face-underline-p 'underline t 'global))
1655 (make-face 'zmacs-region "Used on highlightes region between point and mark.")
1656 (make-face 'isearch "Used on region matched by isearch.")
1657 (make-face 'list-mode-item-selected
1658 "Face for the selected list item in list-mode.")
1659 (make-face 'highlight "Highlight face.")
1660 (make-face 'primary-selection "Primary selection face.")
1661 (make-face 'secondary-selection "Secondary selection face.")
1662
1663 ;; Several useful color faces.
1664 (eval-when-compile (load "cl-macs"))
1665 (dolist (color '(red green blue yellow))
1666 (make-face color (concat (symbol-name color) " text."))
1667 (set-face-foreground color (symbol-name color) nil 'color))
1668
1669 ;; Make some useful faces. This happens very early, before creating
1670 ;; the first non-stream device. We initialize the tty global values here.
1671 ;; We cannot initialize the X global values here because they depend
1672 ;; on having already resourced the global face specs, which happens
1673 ;; when the first X device is created.
1674
1675 (set-face-background-pixmap 'modeline [nothing])
1676
1677 (when (featurep 'tty)
1678 (set-face-highlight-p 'bold t 'global 'tty)
1679 (set-face-underline-p 'italic t 'global 'tty)
1680 (set-face-highlight-p 'bold-italic t 'global 'tty)
1681 (set-face-underline-p 'bold-italic t 'global 'tty)
1682 (set-face-highlight-p 'highlight t 'global 'tty)
1683 (set-face-reverse-p 'text-cursor t 'global 'tty)
1684 (set-face-reverse-p 'modeline t 'global 'tty)
1685 (set-face-reverse-p 'zmacs-region t 'global 'tty)
1686 (set-face-reverse-p 'primary-selection t 'global 'tty)
1687 (set-face-underline-p 'secondary-selection t 'global 'tty)
1688 (set-face-reverse-p 'list-mode-item-selected t 'global 'tty)
1689 (set-face-reverse-p 'isearch t 'global 'tty)
1690 )
1691
1692 ;;; faces.el ends here