annotate lisp/specifier.el @ 872:79c6ff3eef26

[xemacs-hg @ 2002-06-20 21:18:01 by ben] font changes etc.; some 21.4 changes mule/mule-msw-init-late.el: Specify charset->windows-registry conversion. mule/mule-x-init.el: Delete extra mule font additions here. Put them in faces.c. cl-macs.el: Document better. font-lock.el: Move Lisp function regexp to lisp-mode.el. lisp-mode.el: Various indentation fixes: Handle flet functions better. Handle argument lists in defuns and flets. Handle quoted lists, e.g. property lists -- don't indent like function calls. Distinguish between lambdas and other lists. lisp-mode.el: Handle this form. faces.el, font-menu.el, font.el, gtk-faces.el, msw-faces.el, msw-font-menu.el, x-faces.el, x-init.el: Major overhaul of face-handling code: -- Fix lots of bogus code in msw-faces.el, msw-font-menu.el, font-menu.el that was "truenaming" font specs -- i.e. in the process of frobbing a particular field in a general user-specified font spec with wildcarded fields, sticking in particular values for all the remaining wildcarded fields. This bug was rampant everywhere except in x-faces.el (the oldest and only correctly written code). This also means that we need to work with font names at all times and not font instances, because a font instance is essentially a truenamed font. -- Total rewrite of extremely junky code in msw-faces.el. Work with names as well as font instances, and return names; stop truenaming when canonicalizing and frobbing; fix handling of the combined style field, i.e. weight/slant (also fixed in font.el). -- Totally rewrite the frobbing functions in faces.el. This time, we frob all the instantiators rather than just computing a single instance value and working backwards. That way, e.g., `bold' will work for all charsets that have bold available, rather than only for whatever charset was part of the computed font instance (another example of the truename virus). Also fix up code to look at the fallbacks (all of them) when no global value present, so we don't need to put something in the global value. Intelligently handle a request to frob a buffer locale, rather than signalling an error. When frobbing instantiators, try hard to figure out what device type is associated with them, and frob each according to its own proper device type. Correctly handle inheritance vectors given as instantiators. Preserve existing tags when putting back frobbed instantiators. Extract out general specifier-frobbing code into specifier.el. Document everything cleanly. Do lots of other things better, etc. -- Don't duplicatively set a global specification for the default font -- it's already in the fallback and we no longer need a default global specification present. Delete various code in x-faces.el and msw-faces.el that duplicated the lists of fonts in faces.c. -- init-global-faces was not being called at all under MS Windows! Major bogosity. That caused device-specific values to get stuck into all the fonts, making it very hard to change them -- setting global specs caused nothing to happen. -- Correct weight names in font.el. -- Lots more font fixups in objects*.c. Printer.el: Warning fix. specifier.el: Add more args to map-specifier. Add various "heuristic" specifier functions to aid in creation of specifier-munging code such as in faces.el. subr.el: New functions. lwlib.c: Fix warning. config.inc.samp: Clean up, add args to control fastcall (not yet supported! the changes needed are in another ws of mine), profile support, vc6 support, union-type. xemacs.dsp, xemacs.mak: Semi-major overhaul. Fix bug where dump-id was always getting recomputed, forcing a redump even when nothing changed. Add support for fastcall. Support edit-and-continue (on by default) with vc6. Use incremental linking when doing a debug compilation. Add support for profiling. Consolidate the various debug flags. Partial support for "batch-compiling" -- compiling many files on a single invocation of the compiler. Doesn't seem to help that much for me, so it's not finished or enabled by default. Remove HAVE_MSW_C_DIRED, we always do. Correct some sloppy use of directories. s/cygwin32.h: Allow pdump to work under Cygwin (mmap is broken, so need to undefine HAVE_MMAP). s/win32-common.h, s/windowsnt.h: Support for fastcall. Add WIN32_ANY for identifying all Win32 variants (Cygwin, native, MinGW). Both of these are properly used in another ws. alloc.c, balloon-x.c, buffer.c, bytecode.c, callint.c, cm.c, cmdloop.c, cmds.c, console-gtk.c, console-gtk.h, console-msw.c, console-msw.h, console-stream.c, console-stream.h, console-tty.c, console-tty.h, console-x.c, console-x.h, console.c, console.h, device-gtk.c, device-msw.c, device-tty.c, device-x.c, device.c, device.h, devslots.h, dialog-gtk.c, dialog-msw.c, dialog-x.c, dialog.c, dired-msw.c, editfns.c, emacs.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.c, extents.c, extents.h, faces.c, fileio.c, fns.c, frame-gtk.c, frame-msw.c, frame-tty.c, frame-x.c, frame.c, frame.h, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-widget.c, glyphs-x.c, glyphs.c, glyphs.h, gui-gtk.c, gui-msw.c, gui-x.c, gui.c, gutter.c, input-method-xlib.c, intl-encap-win32.c, intl-win32.c, keymap.c, lisp.h, macros.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, menubar.h, minibuf.c, mule-charset.c, nt.c, objects-gtk.c, objects-gtk.h, objects-msw.c, objects-msw.h, objects-tty.c, objects-tty.h, objects-x.c, objects-x.h, objects.c, objects.h, postgresql.c, print.c, process.h, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-tty.c, redisplay-x.c, redisplay.c, redisplay.h, scrollbar-gtk.c, scrollbar-msw.c, scrollbar-x.c, scrollbar.c, select-gtk.c, select-msw.c, select-x.c, select.c, signal.c, sound.c, specifier.c, symbols.c, syntax.c, sysdep.c, syssignal.h, syswindows.h, toolbar-common.c, toolbar-gtk.c, toolbar-msw.c, toolbar-x.c, toolbar.c, unicode.c, window.c, window.h: The following are the major changes made: (1) Separation of various header files into an external and an internal version, similar to the existing separation of process.h and procimpl.h. Eventually this should be done for all Lisp objects. The external version has the same name as currently; the internal adds -impl. The external file has XFOO() macros for objects, but the structure is opaque and defined only in the internal file. It's now reasonable to move all prototypes in lisp.h into the appropriate external file, and this should be done. Currently, separation has been done on extents.h, objects*.h, console.h, device.h, frame.h, and window.h. For c/d/f/w, the most basic properties are available in the external header file, with the macros resolving to functions. In the internal header file, the macros are redefined to directly access the structure. Also, the global MARK_FOO_CHANGED macros have been made into functions so that they can be accessed without needing to include lots of -impl headers -- they are used in almost exclusively in non-time-critical functions, and take up enough time that the function overhead will be negligible. Similarly, the function overhead from making the basic properties mentioned above into functions is negligible, and code that does heavy accessing of c/d/f/w structures inevitably ends up needing the internal header files, anyway. (2) More face changes. -- Major rewrite of objects-msw.c. Now handles wildcard specs properly, rather than "truenaming" (or even worse, signalling an error, which previously happened with some of the fallbacks if you tried to use them in make-font-instance!). -- Split charset matching of fonts into two stages -- one to find a font specifically designed for a particular charset (by examining its registry), the second to find a Unicode font that can support the charset. This needs to proceed as two complete, separate instantiations in order to work properly (otherwise many of the fonts in the HELLO page look wrong). This should also make it easy to support iso10646 (Unicode) fonts under X. -- All default values for fonts are now completely specified in the fallbacks. Stuff from mule-x-init.el has all been moved here, merged with the existing specs, and totally rethought so you get sensible results. (HELLO now looks much better!). -- Generalize the "default X/GTK device" stuff into a per-device-type "default device". -- Add mswindows-{set-}charset-registry. In time, charset<->code-page conversion functions will be removed. -- Wrap protective code around calls to compute device specifier tags, and do this computation before calling the face initialization code because the latter may need these tags to be correctly updated. (3) Other changes. EmacsFrame.c, glyphs-msw.c, eval.c, gui-x.c, intl-encap-win32.c, search.c, signal.c, toolbar-msw.c, unicode.c: Warning fixes. config.h.in: #undefs meant to be frobbed by configure *MUST* go inside of #ifndef WIN32_NO_CONFIGURE, and everything else *MUST* go outside! eval.c: Let detailed backtraces be detailed. specifier.c: Don't override user's print-string-length/print-length settings. glyphs.c: New function image-instance-instantiator. config.h.in, sysdep.c: Changes for fastcall. sysdep.c, nt.c: Fix up a previous botched patch that tried to add support for both EEXIST and EACCES. IF THE BOTCHED PATCH WENT INTO 21.4, THIS FIXUP NEEDS TO GO IN, TOO. search.c: Fix *evil* crash due to incorrect synching of syntax-cache code with 21.1. THIS SHOULD GO INTO 21.4.
author ben
date Thu, 20 Jun 2002 21:19:10 +0000
parents 943eaba38521
children ec2d1e636272
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
1 ;;; specifier.el --- Lisp interface to specifiers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
2
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
3 ;; Copyright (C) 1997 Free Software Foundation, Inc.
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
4 ;; Copyright (C) 1995, 1996, 2000, 2002 Ben Wing.
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
5
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
6 ;; Author: Ben Wing <ben@xemacs.org>
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
7 ;; Keywords: internal, dumped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
8
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
9 ;;; Synched up with: Not in FSF.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
10
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
11 ;; This file is part of XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
12
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
13 ;; XEmacs is free software; you can redistribute it and/or modify it
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
14 ;; under the terms of the GNU General Public License as published by
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
16 ;; any later version.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
17
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
18 ;; XEmacs is distributed in the hope that it will be useful, but
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
21 ;; General Public License for more details.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
22
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
24 ;; along with XEmacs; see the file COPYING. If not, write to the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
25 ;; Free Software Foundation, 59 Temple Place - Suite 330,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
26 ;; Boston, MA 02111-1307, USA.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
27
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
28 ;;; Commentary:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
29
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
30 ;; This file is dumped with XEmacs.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
31
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
32 ;;; Code:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
33
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
34 (defun make-specifier-and-init (type spec-list &optional dont-canonicalize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
35 "Create and initialize a new specifier.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
36
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
37 This is a front-end onto `make-specifier' that allows you to create a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
38 specifier and add specs to it at the same time. TYPE specifies the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
39 specifier type. SPEC-LIST supplies the specification(s) to be added
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
40 to the specifier. Normally, almost any reasonable abbreviation of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
41 full spec-list form is accepted, and is converted to the full form;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
42 however, if optional argument DONT-CANONICALIZE is non-nil, this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
43 conversion is not performed, and the SPEC-LIST must already be in full
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
44 form. See `canonicalize-spec-list'."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
45 (let ((sp (make-specifier type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
46 (if (not dont-canonicalize)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
47 (setq spec-list (canonicalize-spec-list spec-list type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
48 (add-spec-list-to-specifier sp spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
49 sp))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
50
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
51 ;; God damn, do I hate dynamic scoping.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
52
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
53 (defun map-specifier (ms-specifier ms-func &optional ms-locale ms-maparg
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
54 ms-tag-set ms-exact-p)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
55 "Apply MS-FUNC to the specification(s) for MS-LOCALE in MS-SPECIFIER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
56
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
57 If MS-LOCALE is a locale, MS-FUNC will be called for that locale.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
58 If MS-LOCALE is a locale type, MS-FUNC will be mapped over all locales
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
59 of that type. If MS-LOCALE is 'all or nil, MS-FUNC will be mapped
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
60 over all locales in MS-SPECIFIER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
61
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
62 MS-TAG-SET and MS-EXACT-P are as in `specifier-spec-list'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
63
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
64 MS-FUNC is called with four arguments: the MS-SPECIFIER, the locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
65 being mapped over, the inst-list for that locale, and the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
66 optional MS-MAPARG. If any invocation of MS-FUNC returns non-nil,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
67 the mapping will stop and the returned value becomes the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
68 value returned from `map-specifier'. Otherwise, `map-specifier'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
69 returns nil."
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
70 (let ((ms-specs (specifier-spec-list ms-specifier ms-locale ms-tag-set
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
71 ms-exact-p))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
72 ms-result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
73 (while (and ms-specs (not ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
74 (let ((ms-this-spec (car ms-specs)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
75 (setq ms-result (funcall ms-func ms-specifier (car ms-this-spec)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
76 (cdr ms-this-spec) ms-maparg))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
77 (setq ms-specs (cdr ms-specs))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
78 ms-result))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
79
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
80 (defun canonicalize-inst-pair (inst-pair specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
81 "Canonicalize the given INST-PAIR.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
82
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
83 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
84 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
85
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
86 Canonicalizing means converting to the full form for an inst-pair, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
87 `(TAG-SET . INSTANTIATOR)'. A single, untagged instantiator is given
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
88 a tag set of nil (the empty set), and a single tag is converted into
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
89 a tag set consisting only of that tag.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
90
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
91 If NOERROR is non-nil, signal an error if the inst-pair is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
92 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
93 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
94 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
95 ;; a) a single instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
96 ;; b) a cons of a tag and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
97 ;; c) a cons of a tag set and an instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
98 (cond ((valid-instantiator-p inst-pair specifier-type)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
99 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
100 (cons nil inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
101
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
102 ((not (consp inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
103 ;; not an inst-pair
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
104 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
105 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
106 (check-valid-instantiator inst-pair specifier-type)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
107
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
108 ((and (valid-specifier-tag-p (car inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
109 (valid-instantiator-p (cdr inst-pair) specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
110 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
111 (cons (list (car inst-pair)) (cdr inst-pair)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
112
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
113 ((and (valid-specifier-tag-set-p (car inst-pair))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
114 (valid-instantiator-p (cdr inst-pair) specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
115 ;; case (c)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
116 inst-pair)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
117
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
118 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
119 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
120 (signal 'error (list "Invalid specifier tag set"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
121 (car inst-pair)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
122
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
123 (defun canonicalize-inst-list (inst-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
124 "Canonicalize the given INST-LIST (a list of inst-pairs).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
125
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
126 SPECIFIER-TYPE specifies the type of specifier that this INST-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
127 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
128
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
129 Canonicalizing means converting to the full form for an inst-list, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
130 `((TAG-SET . INSTANTIATOR) ...)'. This function accepts a single
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
131 inst-pair or any abbreviation thereof or a list of (possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
132 abbreviated) inst-pairs. (See `canonicalize-inst-pair'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
133
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
134 If NOERROR is non-nil, signal an error if the inst-list is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
135 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
136
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
137 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
138 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
139 ;; a) an inst-pair or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
140 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
141 (let ((result (canonicalize-inst-pair inst-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
142 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
143 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
144 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
145
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
146 (if (not (consp inst-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
147 ;; not an inst-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
148 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
149 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
150 (check-valid-instantiator inst-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
151
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
152 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
153 (catch 'cann-inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
154 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
155 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
156 (let ((rest inst-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
157 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
158 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
159 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
160 (if noerror (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
161 (signal 'error (list "Invalid list format" inst-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
162 (let ((res2 (canonicalize-inst-pair (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
163 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
164 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
165 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
166 ;; otherwise canonicalize-inst-pair would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
167 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
168 (throw 'cann-inst-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
169 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
170 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
171 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
172
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
173 (defun canonicalize-spec (spec specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
174 "Canonicalize the given SPEC (a specification).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
175
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
176 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
177 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
178
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
179 Canonicalizing means converting to the full form for a spec, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
180 `(LOCALE (TAG-SET . INSTANTIATOR) ...)'. This function accepts a
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
181 possibly abbreviated inst-list or a cons of a locale and a possibly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
182 abbreviated inst-list. (See `canonicalize-inst-list'.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
183
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
184 If NOERROR is nil, signal an error if the specification is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
185 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
186 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
187 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
188 ;; a) an inst-list or some abbreviation thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
189 ;; b) a cons of a locale and an inst-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
190 (let ((result (canonicalize-inst-list spec specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
191 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
192 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
193 (cons 'global result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
194
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
195 (if (not (consp spec))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
196 ;; not a spec.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
197 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
198 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
199 (check-valid-instantiator spec specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
200
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
201 (if (not (valid-specifier-locale-p (car spec)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
202 ;; invalid locale.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
203 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
204 (signal 'error (list "Invalid specifier locale" (car spec))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
205
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
206 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
207 (let ((result (canonicalize-inst-list (cdr spec) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
208 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
209 (if (eq result t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
210 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
211 ;; otherwise canonicalize-inst-list would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
212 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
213 t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
214 (cons (car spec) result))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
215
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
216 (defun canonicalize-spec-list (spec-list specifier-type &optional noerror)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
217 "Canonicalize the given SPEC-LIST (a list of specifications).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
218
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
219 SPECIFIER-TYPE specifies the type of specifier that this SPEC-LIST
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
220 will be used for.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
221
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
222 Canonicalizing means converting to the full form for a spec-list, i.e.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
223 `((LOCALE (TAG-SET . INSTANTIATOR) ...) ...)'. This function accepts
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
224 a possibly abbreviated specification or a list of such things. (See
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
225 `canonicalize-spec'.) This is the function used to convert spec-lists
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
226 accepted by `set-specifier' and such into a form suitable for
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
227 `add-spec-list-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
228
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
229 This function tries extremely hard to resolve any ambiguities,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
230 and the built-in specifier types (font, image, toolbar, etc.) are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
231 designed so that there won't be any ambiguities.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
232
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
233 If NOERROR is nil, signal an error if the spec-list is invalid;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
234 otherwise return t."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
235 ;; OK, the possibilities are:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
236 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
237 ;; a) a spec or various abbreviations thereof
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
238 ;; b) a list of (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
239 (let ((result (canonicalize-spec spec-list specifier-type t)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
240 (if (not (eq result t))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
241 ;; case (a)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
242 (list result)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
243
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
244 (if (not (consp spec-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
245 ;; not a spec-list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
246 (if noerror t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
247 ;; this will signal an appropriate error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
248 (check-valid-instantiator spec-list specifier-type))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
249
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
250 ;; case (b)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
251 (catch 'cann-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
252 ;; don't use mapcar here; we need to catch the case of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
253 ;; an invalid list.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
254 (let ((rest spec-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
255 (result nil))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
256 (while rest
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
257 (if (not (consp rest))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
258 (if noerror (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
259 (signal 'error (list "Invalid list format" spec-list)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
260 (let ((res2 (canonicalize-spec (car rest) specifier-type
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
261 noerror)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
262 (if (eq res2 t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
263 ;; at this point, we know we're noerror because
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
264 ;; otherwise canonicalize-spec would have
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
265 ;; signalled an error.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
266 (throw 'cann-spec-list t)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
267 (setq result (cons res2 result)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
268 (setq rest (cdr rest)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
269 (nreverse result)))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
270
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
271 (defun set-specifier (specifier value &optional locale tag-set how-to-add)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
272 "Add a specification or specifications to SPECIFIER.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
273
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
274 This function adds a specification of VALUE in locale LOCALE.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
275 LOCALE indicates where this specification is active, and should be
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
276 a buffer, a window, a frame, a device, or the symbol `global' to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
277 indicate that it applies everywhere. LOCALE usually defaults to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
278 `global' if omitted.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
279
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
280 VALUE is usually what is called an \"instantiator\" (which, roughly
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
281 speaking, corresponds to the \"value\" of the property governed by
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
282 SPECIFIER). The valid instantiators for SPECIFIER depend on the type
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
283 of SPECIFIER (which you can determine using `specifier-type'). The
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
284 specifier `scrollbar-width', for example, is of type `integer',
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
285 meaning its valid instantiators are integers. The specifier governing
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
286 the background color of the `default' face (you can retrieve this
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
287 specifier using `(face-background 'default)') is of type `color',
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
288 meaning its valid instantiators are strings naming colors and
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
289 color-instance objects. For some types of specifiers, such as `image'
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
290 and `toolbar', the instantiators can be very complex. Generally this
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
291 is documented in the appropriate creation function --
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
292 e.g. `make-color-specifier', `make-font-specifier',
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
293 `make-image-specifier' -- or in the global variable holding the most
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
294 common specifier for that type (`default-toolbar', `default-gutter',
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
295 `current-display-table').
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
296
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
297 NOTE: It does *not* work to give a VALUE of nil as a way of removing the
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
298 specifications for a locale -- for many specifier types, such as `boolean',
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
299 nil is a perfectly legitimate value to set. Use `remove-specifier'
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
300 instead. (And keep in mind that, if you omit the LOCALE argument to
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
301 `remove-specifier', it removes *all* specifications! If you want to remove
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
302 just the `global' specification, make sure to specify a LOCALE of
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
303 `global'.)
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
304
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
305 VALUE can also be a list of instantiators. This means basically,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
306 \"try each one in turn until you get one that works\". This allows
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
307 you to give funky instantiators that may only work in some cases,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
308 and provide more normal backups for the other cases. (For example,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
309 you might like the color \"darkseagreen2\", but some X servers
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
310 don't recognize this color, so you could provide a backup
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
311 \"forest green\". Color TTY devices probably won't recognize this
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
312 either, so you could provide a second backup \"green\". You'd
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
313 do this by specifying this list of instantiators:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
314
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
315 '(\"darkseagreen2\" \"forest green\" \"green\")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
316
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
317 VALUE can also be various more complicated forms; see below.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
318
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
319 Optional argument TAG-SET is a tag or a list of tags, to be associated
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
320 with the VALUE. Tags are symbols (usually naming device types, such
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
321 as `x' and `tty', or device classes, such as `color', `mono', and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
322 `grayscale'); specifying a TAG-SET restricts the scope of VALUE to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
323 devices that match all specified tags. (You can also create your
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
324 own tags using `define-specifier-tag', and use them to identify
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
325 specifications added by you, so you can remove them later.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
326
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
327 Optional argument HOW-TO-ADD should be either nil or one of the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
328 symbols `prepend', `append', `remove-tag-set-prepend',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
329 `remove-tag-set-append', `remove-locale', `remove-locale-type',
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
330 or `remove-all'. This specifies what to do with existing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
331 specifications in LOCALE (and possibly elsewhere in the specifier).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
332 Most of the time, you do not need to worry about this argument;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
333 the default behavior of `remove-tag-set-prepend' is usually fine.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
334 See `copy-specifier' and `add-spec-to-specifier' for a full
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
335 description of what each of these means.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
336
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
337 \[VALUE can actually be anything acceptable to `canonicalize-spec-list';
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
338 this includes, among other things:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
339
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
340 -- a cons of a locale and an instantiator (or list of instantiators)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
341 -- a cons of a tag or tag-set and an instantiator (or list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
342 instantiators)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
343 -- a cons of a locale and the previous type of item
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
344 -- a list of one or more of any of the previous types of items
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
345
771
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
346 However, this usage is deprecated. Either iterate and call `set-specifier'
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
347 multiple times, or use the lower-level `add-spec-list-to-specifier'. Also,
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
348 in these cases, you cannot give a LOCALE or TAG-SET, because they do not
943eaba38521 [xemacs-hg @ 2002-03-13 08:51:24 by ben]
ben
parents: 630
diff changeset
349 make sense. (You will probably get an error if you try this.)]
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
350
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
351 Finally, VALUE can itself be a specifier (of the same type as
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
352 SPECIFIER), if you want to copy specifications from one specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
353 to another; this is equivalent to calling `copy-specifier', and
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
354 LOCALE, TAG-SET, and HOW-TO-ADD have the same semantics as with
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
355 that function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
356
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
357 Note that `set-specifier' is exactly complementary to `specifier-specs'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
358 except in the case where SPECIFIER has no specs at all in it but nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
359 is a valid instantiator (in that case, `specifier-specs' will return
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
360 nil (meaning no specs) and `set-specifier' will interpret the `nil'
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
361 as meaning \"I'm adding a global instantiator and its value is `nil'\"),
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
362 or in strange cases where there is an ambiguity between a spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
363 and an inst-list, etc. (The built-in specifier types are designed
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
364 in such a way as to avoid any such ambiguities.)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
365
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
366 NOTE: If you want to work with spec-lists, you should probably not
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
367 use either `set-specifier' or `specifier-specs', but should use the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
368 lower-level functions `add-spec-list-to-specifier' and `specifier-spec-list'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
369 These functions always work with fully-qualified spec-lists; thus, there
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
370 is no possibility for ambiguity and no need to go through the function
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
371 `canonicalize-spec-list', which is potentially time-consuming."
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
372
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
373 ;; backward compatibility: the old function had HOW-TO-ADD as the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 ;; third argument and no arguments after that.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 ;; #### this should disappear at some point.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 (if (and (null how-to-add)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 (memq locale '(prepend append remove-tag-set-prepend
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
378 remove-tag-set-append remove-locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
379 remove-locale-type remove-all)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 (setq how-to-add locale)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 (setq locale nil)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 ;; proper beginning of the function.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
385 (let ((is-valid (valid-instantiator-p value (specifier-type specifier)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
386 (nval value))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
387 (cond ((and (not is-valid) (specifierp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 (copy-specifier nval specifier locale tag-set nil how-to-add))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 (t
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 (if tag-set
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 (if (not (listp tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393 (setq tag-set (list tag-set)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 ;; You tend to get more accurate errors
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395 ;; for a variety of cases if you call
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 ;; canonicalize-tag-set here.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
397 (setq tag-set (canonicalize-tag-set tag-set))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
398 (if (and (not is-valid) (consp nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
399 (setq nval
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 (mapcar #'(lambda (x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
401 (check-valid-instantiator
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
402 x (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 (cons tag-set x))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 nval))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 (setq nval (cons tag-set nval)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 (if locale
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 (setq nval (cons locale nval)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409 specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 (canonicalize-spec-list nval (specifier-type specifier))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 how-to-add))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 value)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
413
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
414 (defun modify-specifier-instances (specifier func &optional args force default
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
415 locale tag-set)
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
416 "Modify all specifications that match LOCALE and TAG-SET by FUNC.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
417
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
418 For each specification that exists for SPECIFIER, in locale LOCALE
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
419 that matches TAG-SET, call the function FUNC with the instance as its
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
420 first argument and with optional arguments ARGS. The result is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
421 used as the new value of the instantiator.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
422
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
423 If there is no specification in the domain LOCALE matching TAG-SET and
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
424 FORCE is non-nil, an explicit one is created from the matching
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
425 specifier instance if that exists or DEFAULT otherwise. If LOCALE is
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
426 not a domain (i.e. a buffer), DEFAULT is always used. FUNC is then
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
427 applied like above and the resulting specification is added."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
428
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
429 (let ((spec-list (specifier-spec-list specifier locale tag-set)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
430 (cond
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
431 (spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
432 ;; Destructively edit the spec-list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
433 (mapc #'(lambda (spec)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
434 (mapc #'(lambda (inst-pair)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
435 (setcdr inst-pair
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
436 (apply func (cdr inst-pair) args)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
437 (cdr spec)))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
438 spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
439 (add-spec-list-to-specifier specifier spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
440 (force
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
441 (set-specifier specifier
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
442 (apply func
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
443 (or (and (valid-specifier-domain-p locale)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
444 (specifier-instance specifier))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
445 default) args)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
446 locale tag-set)))))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
447
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 (defmacro let-specifier (specifier-list &rest body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 "Add specifier specs, evaluate forms in BODY and restore the specifiers.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 \(let-specifier SPECIFIER-LIST BODY...)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 Each element of SPECIFIER-LIST should look like this:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 \(SPECIFIER VALUE &optional LOCALE TAG-SET HOW-TO-ADD).
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 SPECIFIER is the specifier to be temporarily modified. VALUE is the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 instantiator to be temporarily added to SPECIFIER in LOCALE. LOCALE,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457 TAG-SET and HOW-TO-ADD have the same meaning as in
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 `add-spec-to-specifier'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 The code resulting from macro expansion will add specifications to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 specifiers using `add-spec-to-specifier'. After BODY is finished, the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 temporary specifications are removed and old spec-lists are restored.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 LOCALE, TAG-SET and HOW-TO-ADD may be omitted, and default to nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 The value of the last form in BODY is returned.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 NOTE: If you want the specifier's instance to change in all
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 circumstances, use (selected-window) as the LOCALE. If LOCALE is nil
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469 or omitted, it defaults to `global'.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 Example:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
472 (let-specifier ((modeline-shadow-thickness 0 (selected-window)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
473 (sit-for 1))"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
474 (check-argument-type 'listp specifier-list)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 (flet ((gensym-frob (x name)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 (if (or (atom x) (eq (car x) 'quote))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 (list x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
478 (list (gensym name) x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 ;; VARLIST is a list of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 ;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 ;; (TAG-SET) (HOW-TO-ADD))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 ;; If any of these is an atom, then a separate symbol is
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 ;; unnecessary, the CAR will contain the atom and CDR will be nil.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 (let* ((varlist (mapcar #'(lambda (listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 (or (and (consp listel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 (<= (length listel) 5)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487 (> (length listel) 1))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 (signal 'error
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 (list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 "should be a list of 2-5 elements"
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 listel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 ;; VALUE, TAG-SET and HOW-TO-ADD are
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 ;; referenced only once, so we needn't
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 ;; frob them with gensym.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495 (list (gensym-frob (nth 0 listel) "specifier-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 (list (nth 1 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 (gensym-frob (nth 2 listel) "locale-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 (list (nth 3 listel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 (list (nth 4 listel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
500 specifier-list))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
501 ;; OLDVALLIST is a list of (OLDVALSYM OLDVALFORM)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 (oldvallist (mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 (list (gensym "old-")
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504 `(specifier-spec-list
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 ,(car (nth 2 varel)))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
507 varlist)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
508 ;; Bind the appropriate variables.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 `(let* (,@(mapcan #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 (delq nil (mapcar
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 #'(lambda (varcons)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 (and (cdr varcons) varcons))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 ,@oldvallist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 (unwind-protect
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
517 (progn
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 ,@(mapcar #'(lambda (varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 `(add-spec-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 ,(car (nth 0 varel)) ,(car (nth 1 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 ,(car (nth 2 varel)) ,(car (nth 3 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 ,(car (nth 4 varel))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 varlist)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 ,@body)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 ;; Reverse the unwinding order, so that using the same
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 ;; specifier multiple times works.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 ,@(apply #'nconc (nreverse (mapcar*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 #'(lambda (oldval varel)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 `((remove-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 ,(car (nth 2 varel)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 (add-spec-list-to-specifier
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 ,(car (nth 0 varel))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 ,(car oldval))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 oldvallist varlist))))))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536
442
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
537 (defun make-integer-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
538 "Return a new `integer' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
539 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
540 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
541 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
542 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
543
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
544 Valid instantiators for integer specifiers are integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
545 (make-specifier-and-init 'integer spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
546
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
547 (defun make-boolean-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
548 "Return a new `boolean' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
549 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
550 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
551 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
552 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
553
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
554 Valid instantiators for boolean specifiers are t and nil."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
555 (make-specifier-and-init 'boolean spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
556
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
557 (defun make-natnum-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
558 "Return a new `natnum' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
559 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
560 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
561 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
562 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
563
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
564 Valid instantiators for natnum specifiers are non-negative integers."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
565 (make-specifier-and-init 'natnum spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
566
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
567 (defun make-generic-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
568 "Return a new `generic' specifier object with the given specification list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
569 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
570 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
571 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
572 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
573
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
574 Valid instantiators for generic specifiers are all Lisp values.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
575 They are returned back unchanged when a specifier is instantiated."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
576 (make-specifier-and-init 'generic spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
577
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
578 (defun make-display-table-specifier (spec-list)
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
579 "Return a new `display-table' specifier object with the given spec list.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
580 SPEC-LIST can be a list of specifications (each of which is a cons of a
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
581 locale and a list of instantiators), a single instantiator, or a list
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
582 of instantiators. See `make-specifier' for more information about
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
583 specifiers.
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
584
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
585 Valid instantiators for display-table specifiers are described in
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
586 detail in the doc string for `current-display-table'."
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
587 (make-specifier-and-init 'display-table spec-list))
abe6d1db359e Import from CVS: tag r21-2-36
cvs
parents: 428
diff changeset
588
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
589 ;; Evaluate this for testing:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
590 ; (cl-prettyexpand '(let-specifier ((modeline-shadow-thickness 0 (selected-window) 'x) (fubar (value) baz)) (sit-for 1)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
592 (define-specifier-tag 'win 'device-on-window-system-p)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
593
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
594 ;; Add tags for device types that don't have support compiled
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 ;; into the binary that we're about to dump. This will prevent
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 ;; code like
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
597 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
598 ;; (set-face-foreground 'default "black" nil '(x color))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
599 ;;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 ;; from producing an error if no X support was compiled in.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
601
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
602 (or (valid-specifier-tag-p 'x)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
603 (define-specifier-tag 'x (lambda (dev) (eq (device-type dev) 'x))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 (or (valid-specifier-tag-p 'tty)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 (define-specifier-tag 'tty (lambda (dev) (eq (device-type dev) 'tty))))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 (or (valid-specifier-tag-p 'mswindows)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 (define-specifier-tag 'mswindows (lambda (dev)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608 (eq (device-type dev) 'mswindows))))
630
ff9d7f21f8d0 [xemacs-hg @ 2001-07-18 12:44:51 by stephent]
stephent
parents: 442
diff changeset
609 (or (valid-specifier-tag-p 'gtk)
ff9d7f21f8d0 [xemacs-hg @ 2001-07-18 12:44:51 by stephent]
stephent
parents: 442
diff changeset
610 (define-specifier-tag 'gtk (lambda (dev) (eq (device-type dev) 'gtk))))
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
611
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
612 ;; Add special tag for use by initialization code. Code that
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
613 ;; sets up default specs should use this tag. Code that needs to
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 ;; override default specs (e.g. the X resource initialization
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
615 ;; code) can safely clear specs with this tag without worrying
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 ;; about clobbering user settings.
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 (define-specifier-tag 'default)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619
872
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
621 ;;; "Heuristic" specifier functions ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
623
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
624 ;;; "Heuristic" is a euphemism for kludge. This stuff works well in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
625 ;;; practice, though.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
626
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
627 ;;; You might view all the contortions we do here and in Face-frob-property
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
628 ;;; as indicative of design failures with specifiers, and perhaps you're
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
629 ;;; right. But in fact almost all code that attempts to interface to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
630 ;;; humans and produce "intuitive" results gets messy, particularly with a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
631 ;;; system as complicated as specifiers, whose complexity results from an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
632 ;;; attempt to work well in many different circumstances. We could create
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
633 ;;; a much simpler system, but the tradeoff would be that you'd have to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
634 ;;; programmatically control all the stuff that gets handled automatically
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
635 ;;; by setting the right specifiers -- and then things wouldn't "just work"
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
636 ;;; if the user simultaneously creates a TTY and X device, or X devices on
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
637 ;;; different types of machines, or wants some buffers to display
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
638 ;;; differently from others, etc. without a lot of hook functions and other
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
639 ;;; glue machinery to set everything up. The result would be just as much
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
640 ;;; complexity, but worse, and much harder to control, since there wouldn't
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
641 ;;; be any standard framework for managing all these hook functions and the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
642 ;;; user would have to be able to write lots of Lisp code to get things
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
643 ;;; working.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
644
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
645 ;;; The problem is that we have no high-level code, e.g. custom, to make it
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
646 ;;; easy for the user to control specifiers nicely. The following
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
647 ;;; lower-level code, though, should make it easier to implement the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
648 ;;; high-level code.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
649
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
650 ;;; #### Something like Face-frob-property, but more general, should be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
651 ;;; created for general specifier frobbing.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
652
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
653 ;;; #### Other possible extensions to specifiers would be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
654 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
655 ;;; (a) the ability to create specifications for particular types of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
656 ;;; buffers, e.g. all C-mode buffers one way, all text-mode buffers
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
657 ;;; another way, etc. Perhaps this should be implemented through hook
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
658 ;;; functions; but that wouldn't easily allow you to `make-face-bold'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
659 ;;; and have it work on these other kinds of specifications. Probably
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
660 ;;; a better way is to extend the tag mechanism so that it can specify
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
661 ;;; things other than device types. One way would be to simply allow
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
662 ;;; tags to have arbitrary elisp attached to them -- a function that
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
663 ;;; takes a domain and returns whether the attached instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
664 ;;; applies. This should be doable given (a) that we now have code to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
665 ;;; allow elisp to be run inside a "sandbox", sufficiently protected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
666 ;;; that it can even be called from redisplay, and (b) the large amount
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
667 ;;; of caching we already have, which would minimize the speed hit.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
668 ;;; However, this still runs into problems -- (a) it requires
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
669 ;;; programming to get anything at all done, and (b) you'll get
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
670 ;;; horrible namespace clashes very quickly. Another possibility to be
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
671 ;;; used in conjunction with this would be vector tags, with an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
672 ;;; extendable mechanism to control their syntax. For example,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
673 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
674 ;;; [tag :mode 'c] (buffer in c-mode)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
675 ;;; [tag :buffer-name "\\*Help: function"] (help-on-function buffers)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
676 ;;; [tag :buffer-coding-system 'japanese-euc] (buffer's coding system is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
677 ;;; EUC-JP)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
678 ;;; [tag :buffer-file-name "^#.*#$"] (autosave files)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
679 ;;; [tag :language-environment "French"] (whenever the global language
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
680 ;;; environment is French)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
681 ;;; [tag :font-height-minimum '(default 12)] (if the height of the default
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
682 ;;; font is at least 12 pixels
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
683 ;;; in this domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
684 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
685 ;;; The general idea is that the properties allowable in a tag vector
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
686 ;;; are extendable, just by specifying the property name and a function
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
687 ;;; of two arguments, the property value and the domain, which should
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
688 ;;; return whether the tag applies. You could imagine very complex
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
689 ;;; behavior (e.g. combining two tags in a single tag set makes an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
690 ;;; `and', and putting the two tags separately with separate (perhaps
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
691 ;;; identical) instantiators makes an `or'. You could effectively do a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
692 ;;; lot of what you might want to do with hooks, but in a much more
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
693 ;;; controllable fashion. Obviously, much of this complexity wouldn't
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
694 ;;; necessarily be directly set by the user -- they wouldn't probably
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
695 ;;; do more than simple tags based on mode, buffer or file name, etc.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
696 ;;; But a higher-level interface could easily have various possible
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
697 ;;; "behaviors" to choose from, implemented using this mechanism.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
698 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
699 ;;; #### WE NEED CUSTOM SUPPORT!
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
700 ;;;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
701 ;;; (b) Another possibility is "partial" inheritance. For example --
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
702 ;;; toolbars and menubars are complex specifications. Currently the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
703 ;;; only way to make a change is to copy the entire value and make the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
704 ;;; necessary modifications. What we would like instead is to be able
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
705 ;;; to construct a mini-menubar that says something like "add this menu
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
706 ;;; here" and combine with everything else. That would require a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
707 ;;; slightly different approach to instantiation. Currently it just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
708 ;;; searches up the tree from specific to general, looking for a match;
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
709 ;;; from this match, it generates the instance. Instead, it would
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
710 ;;; potentially have to record all the matches it found and pass a list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
711 ;;; of them to the instantiation function. To implement this, we would
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
712 ;;; create another specifier method "instantiator_inherits_up", which
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
713 ;;; looks at the instantiator to determine if it calls for combining
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
714 ;;; itself with the value higher up. this tells the specifier code
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
715 ;;; whether to stop now or keep going. It would then pass a Dynarr of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
716 ;;; the instantiators to the instantiate method, which might be a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
717 ;;; special version, e.g. "instantiate_multi".
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
718
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
719 (defun instance-to-instantiator (inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
720 "Convert an instance to an instantiator.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
721 If we have an instance object, we fetch the instantiator that generated the object. Otherwise, we just return the instance."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
722 (cond ((font-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
723 (setq inst (font-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
724 ((color-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
725 (setq inst (color-instance-name inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
726 ((image-instance-p inst)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
727 (setq inst (image-instance-instantiator inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
728 (t inst)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
729
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
730 (defun device-type-matches-spec (devtype devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
731 ;; Return DEVTYPE (a devtype) if it matches DEVTYPE-SPEC, else nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
732 ;; DEVTYPE-SPEC can be nil (all types OK), a device type (only that type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
733 ;; OK), or `window-system' -- window system device types OK.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
734 (cond ((not devtype-spec) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
735 ((eq devtype-spec 'window-system)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
736 (and (not (memq devtype '(tty stream))) devtype))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
737 (t (and (eq devtype devtype-spec) devtype))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
738
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
739 (defun add-tag-to-inst-list (inst-list tag-set)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
740 "Add TAG-SET (tag or tag-set) to all tags in INST-LIST."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
741 ;; Ah, all is sweetness and light with `loop'
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
742 (if (null tag-set) inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
743 (loop for (t2 . x2) in inst-list
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
744 for newt2 = (delete-duplicates
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
745 (append (if (listp tag-set) tag-set (list tag-set))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
746 (if (listp t2) t2 (list t2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
747 collect (cons newt2 x2))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
748
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
749 (defun derive-domain-from-locale (locale &optional devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
750 "Given a locale, try to derive the \"most reasonable\" domain.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
751
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
752 This is a heuristic \(\"works most of the time\") algorithm.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
753
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
754 \[Remember that, in specifiers, locales are what you attach specifications or
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
755 \"instantiators\" to, and domains are the contexts in which you can
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
756 retrieve the value or \"instance\" of the specifier. Not all locales are
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
757 domains. In particular, buffers are locales but not domains because
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
758 buffers may be displayed in different windows on different frames, and thus
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
759 end up with different values if the frames each have a frame-local
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
760 instantiator and the instantiators are different. However, we may well
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
761 find ourselves in a situation where we want to figure out the most likely
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
762 value of a specifier in a buffer -- for example we might conceptually want
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
763 to make a buffer's modeline face be bold, so we need to figure out what the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
764 current face is. If the buffer already has an instantiator, it's easy; but
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
765 if it doesn't, we want to do something reasonable rather than just issue an
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
766 error, even though technically the value is not well-defined. We want
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
767 something that gives the right answer most of the time.]
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
768
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
769 LOCALE is a specifier locale -- i.e. a buffer, window, frame, device, the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
770 symbol `global', or nil, meaning the same as `global'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
771
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
772 DEVTYPE-SPEC, if given, can restrict the possible return values to domains
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
773 on devices of that device type; or if it's `window-system', to domains on
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
774 window-system devices.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
775
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
776 CURRENT-DEVICE is what should be considered as the \"selected device\" when
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
777 this value is needed. It defaults to the currently selected device.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
778
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
779 -- If LOCALE is a domain, it's simply returned.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
780 -- If LOCALE is `all', `global', or nil, we return CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
781 -- If LOCALE is a buffer, we use `get-buffer-window' to find a window viewing
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
782 the buffer, and return it if there is one; otherwise we return the selected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
783 window on CURRENT-DEVICE.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
784
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
785 The return value may be nil if the only possible values don't agree with
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
786 DEVTYPE-SPEC."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
787 ;; DEVICE aims to be the selected device, but picks some other
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
788 ;; device if that won't work. may be nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
789 (let* ((device (or current-device (selected-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
790 (device (if (device-type-matches-spec (device-type device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
791 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
792 device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
793 (first
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
794 (delete-if-not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
795 #'(lambda (x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
796 (device-type-matches-spec (device-type x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
797 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
798 (device-list))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
799 (cond ((memq locale '(all nil global)) device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
800 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
801 (and (device-type-matches-spec (device-type (dfw-device locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
802 devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
803 locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
804 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
805 (let ((win (get-buffer-window locale t devtype-spec)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
806 (or win (and device (selected-window device))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
807
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
808 (defun derive-device-type-from-tag-set (tag-set &optional try-stages
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
809 devtype-spec current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
810 "Given a tag set, try (heuristically) to get a device type from it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
811
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
812 There are three stages that this function proceeds through, each one trying
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
813 harder than the previous to get a value. TRY-STAGES controls how many
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
814 stages to try. If nil or 1, only stage 1 is done; if 2; stages 1 and 2 are
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
815 done; if 3, stages 1-3 are done; if t, all stages are done (currently 1-3).
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
816
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
817 Stage 1 looks at the tags themselves to see if any of them are device-type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
818 tags. If so, it returns the device type. If there is more than one device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
819 type, this tag can never match anything, but we go ahead and return one of
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
820 them. If no device types in the tags, we fail.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
821
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
822 Stage 2 runs all devices through the tag set to see if any match, and
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
823 accumulate a list of device types of all matching devices. If there is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
824 exactly one device type in the list, we return it, else fail.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
825
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
826 Stage 3 picks up from where stage 2 left off, and tries hard to return
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
827 *SOME* device type in all possible situations, modulo the DEVTYPE-SPEC
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
828 flag. \(DEVTYPE-SPEC and CURRENT-DEVICE are the same as in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
829 `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
830
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
831 Specifically:
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
832
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
833 \(a) if no matching devices, return the selected device's type.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
834 \(b) if more than device type and the selected device's type is
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
835 listed, use it.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
836 \(c) else, pick one of the device types (currently the first).
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
837
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
838 This will never return a device type that's incompatible with the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
839 DEVTYPE-SPEC flag; thus, it may return nil."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
840 (or try-stages (setq try-stages 1))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
841 (if (eq try-stages t) (setq try-stages 3))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
842 (check-argument-range try-stages 1 3)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
843 (flet ((delete-wrong-type (x)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
844 (delete-if-not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
845 #'(lambda (y)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
846 (device-type-matches-spec y devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
847 x)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
848 (let ((both (intersection (device-type-list)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
849 (canonicalize-tag-set tag-set))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
850 ;; shouldn't be more than one (will fail), but whatever
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
851 (if both (first (delete-wrong-type both))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
852 (and (>= try-stages 2)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
853 ;; no device types mentioned. try the hard way,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
854 ;; i.e. check each existing device to see if it will
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
855 ;; pass muster.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
856 (let ((okdevs
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
857 (delete-wrong-type
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
858 (delete-duplicates
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
859 (mapcan
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
860 #'(lambda (dev)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
861 (and (device-matches-specifier-tag-set-p
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
862 dev tag-set)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
863 (list (device-type dev))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
864 (device-list)))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
865 (devtype (cond ((or (null devtype-spec)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
866 (eq devtype-spec 'window-system))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
867 (let ((dev (derive-domain-from-locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
868 'global devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
869 current-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
870 (and dev (device-type dev))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
871 (t devtype-spec))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
872 (cond ((= 1 (length okdevs)) (car okdevs))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
873 ((< try-stages 3) nil)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
874 ((null okdevs) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
875 ((memq devtype okdevs) devtype)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
876 (t (car okdevs)))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
877
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
878 ;; Sheesh, the things you do to get "intuitive" behavior.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
879 (defun derive-device-type-from-locale-and-tag-set (locale tag-set
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
880 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
881 current-device)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
882 "Try to derive a device type from a locale and tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
883
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
884 If the locale is a domain, use the domain's device type. Else, if the tag
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
885 set uniquely specifies a device type, use it. Else, if a buffer is given,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
886 find a window visiting the buffer, and if any, use its device type.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
887 Finally, go back to the tag set and \"try harder\" -- if the selected
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
888 device matches the tag set, use its device type, else use some valid device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
889 type from the tag set.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
890
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
891 DEVTYPE-SPEC and CURRENT-DEVICE as in `derive-domain-from-locale'."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
892
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
893 (cond ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
894 ;; if locale is a domain, then it must match DEVTYPE-SPEC,
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
895 ;; or we exit immediately with nil.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
896 (device-type-matches-spec (device-type (dfw-device locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
897 devtype-spec))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
898 ((derive-device-type-from-tag-set tag-set 2 devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
899 current-device))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
900 ((and (bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
901 (let ((win (get-buffer-window locale t devtype-spec)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
902 (and win (device-type (dfw-device win))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
903 ((derive-device-type-from-tag-set tag-set t devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
904 current-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
905
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
906 (defun derive-specifier-specs-from-locale (specifier locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
907 &optional devtype-spec
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
908 current-device
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
909 global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
910 "Heuristically find the specs of a specifier in a locale.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
911
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
912 This tries to find some reasonable instantiators that are most likely to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
913 correspond to the specifier's \"value\" (i.e. instance) in a particular
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
914 locale, even when the user has not specifically set any such instantiators.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
915 This is useful for functions that want to modify the instance of a
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
916 specifier in a particular locale, and only in that locale.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
917
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
918 Keep in mind that this is a heuristic (i.e. kludge) function, and that it
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
919 may not always give the right results, since the operation is not
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
920 technically well-defined in many cases! (See `derive-domain-from-locale'.)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
921
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
922 DEVTYPE-SPEC and CURRENT-DEVICE are as in `derive-domain-from-locale'.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
923
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
924 The return value is an inst-list, i.e.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
925
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
926 ((TAG-SET . INSTANTIATOR) ...)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
927
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
928 More specifically, if there is already a spec in the locale, it's just
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
929 returned. Otherwise, if LOCALE is `global', `all', or nil: If
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
930 GLOBAL-USE-FALLBACK is non-nil, the fallback is fetched, and returned, with
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
931 `default' added to the tag set; else, we use CURRENT-DEVICE (defaulting to
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
932 the selected device) as a domain and proceed as in the following. If
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
933 LOCALE is a domain (window, frame, device), the specifier's instance in
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
934 that domain is computed, and converted back to an instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
935 \(`instance-to-instantiator'). Else, if LOCALE is a buffer, we use
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
936 `derive-domain-from-locale' to heuristically get a likely domain, and
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
937 proceed as if LOCALE were a domain."
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
938 (if (memq locale '(all nil)) (setq locale 'global))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
939 (let ((current (specifier-spec-list specifier locale)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
940 (if current (cdar current)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
941 ;; case 1: a global locale, fallbacks
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
942 (cond ((and (eq locale 'global) global-use-fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
943 ;; if nothing there globally, retrieve the fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
944 ;; this is either an inst-list or a specifier. in the
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
945 ;; latter case, we need to recursively retrieve its
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
946 ;; fallback.
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
947 (let (sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
948 (fallback (specifier-fallback specifier)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
949 (while (specifierp fallback)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
950 (setq sofar (nconc sofar
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
951 (cdar (specifier-spec-list fallback
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
952 'global))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
953 (setq fallback (specifier-fallback fallback)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
954 (add-tag-to-inst-list (nconc sofar fallback) 'default)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
955 (t
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
956 (let (domain)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
957 ;; case 2: window, frame, device locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
958 (cond ((eq locale 'global)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
959 (setq domain (or current-device (selected-device))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
960 ((valid-specifier-domain-p locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
961 (setq domain locale))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
962 ;; case 3: buffer locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
963 ((bufferp locale)
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
964 (setq domain (derive-domain-from-locale
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
965 locale devtype-spec current-device)))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
966 (t nil))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
967 ;; retrieve an instance, convert back to instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
968 (when domain
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
969 (let ((inst
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
970 (instance-to-instantiator
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
971 (specifier-instance specifier domain))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
972 (list (cons nil inst))))))))))
79c6ff3eef26 [xemacs-hg @ 2002-06-20 21:18:01 by ben]
ben
parents: 771
diff changeset
973
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
974 ;;; specifier.el ends here