comparison man/lispref/specifiers.texi @ 2953:c7d4a681eb2c

[xemacs-hg @ 2005-09-26 08:41:45 by ben] add specifier-instantiator and friends specifier.c: Add `specifier-instantiator' and related primitives. lispref/glyphs.texi, lispref/lispref.texi, lispref/specifiers.texi: Use "instantiation" not "instancing". Fix some places where "specifier" is used to mean "instantiator".
author ben
date Mon, 26 Sep 2005 08:41:57 +0000
parents 6bca5896aab2
children f200f93c0b69
comparison
equal deleted inserted replaced
2952:861a7995b9fe 2953:c7d4a681eb2c
12 should vary according to @emph{display context}, a window, a frame, or 12 should vary according to @emph{display context}, a window, a frame, or
13 device. The value of many built-in properties, such as the font, 13 device. The value of many built-in properties, such as the font,
14 foreground, background, and such properties of a face and variables 14 foreground, background, and such properties of a face and variables
15 such as @code{modeline-shadow-thickness} and 15 such as @code{modeline-shadow-thickness} and
16 @code{top-toolbar-height}, is actually a specifier object. The 16 @code{top-toolbar-height}, is actually a specifier object. The
17 specifier object, in turn, is ``instanced'' in a particular situation 17 specifier object, in turn, is ``instantiated'' in a particular situation
18 to yield the real value of the property in the current context. 18 to yield the real value of the property in the current context.
19 19
20 @defun specifierp object 20 @defun specifierp object
21 This function returns non-@code{nil} if @var{object} is a specifier. 21 This function returns non-@code{nil} if @var{object} is a specifier.
22 @end defun 22 @end defun
26 display and other properties to vary 26 display and other properties to vary
27 (under user control) in a wide variety 27 (under user control) in a wide variety
28 of contexts. 28 of contexts.
29 * Simple Specifier Usage:: Getting started with specifiers. 29 * Simple Specifier Usage:: Getting started with specifiers.
30 * Specifiers In-Depth:: Gory details about specifier innards. 30 * Specifiers In-Depth:: Gory details about specifier innards.
31 * Specifier Instancing:: Instancing means obtaining the ``value'' of 31 * Specifier Instantiation:: Instantiation means obtaining the ``value'' of
32 a specifier in a particular context. 32 a specifier in a particular context.
33 * Specifier Types:: Specifiers come in different flavors. 33 * Specifier Types:: Specifiers come in different flavors.
34 * Adding Specifications:: Specifications control a specifier's ``value'' 34 * Adding Specifications:: Specifications control a specifier's ``value''
35 by giving conditions under which a 35 by giving conditions under which a
36 particular value is valid. 36 particular value is valid.
37 * Retrieving Specifications:: Querying a specifier's specifications. 37 * Retrieving Specifications:: Querying a specifier's specifications.
38 * Specifier Tag Functions:: Working with specifier tags. 38 * Specifier Tag Functions:: Working with specifier tags.
39 * Specifier Instancing Functions:: 39 * Specifier Instantiation Functions::
40 Functions to instance a specifier. 40 Functions to instantiate a specifier.
41 * Specifier Examples:: Making all this stuff clearer. 41 * Specifier Examples:: Making all this stuff clearer.
42 * Creating Specifiers:: Creating specifiers for your own use. 42 * Creating Specifiers:: Creating specifiers for your own use.
43 * Specifier Validation Functions:: 43 * Specifier Validation Functions::
44 Validating the components of a specifier. 44 Validating the components of a specifier.
45 * Other Specification Functions:: 45 * Other Specification Functions::
87 can fall back to ``yellow'' on devices where only ANSI (4-bit) color 87 can fall back to ``yellow'' on devices where only ANSI (4-bit) color
88 is available. The complex calculations and device querying are 88 is available. The complex calculations and device querying are
89 transparent to both user and programmer. You ask for what you want; 89 transparent to both user and programmer. You ask for what you want;
90 it's up to XEmacs to provide it, or a reasonable approximation. 90 it's up to XEmacs to provide it, or a reasonable approximation.
91 91
92 We call such a declaration a @dfn{specification}. A @dfn{specification} 92 We call such a declaration a @dfn{specification}. A
93 applies in a particular @dfn{locale}, which is a window, buffer, frame, 93 @dfn{specification} applies in a particular @dfn{locale}, which is a
94 device, or the global locale. The value part of the specification is 94 window, buffer, frame, device, or the global locale. The value part
95 called an @dfn{instantiator}. The process of determining the value in a 95 of the specification is called an @dfn{instantiator}. The process of
96 particular context, or @dfn{domain}, is called @dfn{instantiation} or 96 determining the value in a particular context, or @dfn{domain}, is
97 @dfn{instancing}. A domain is a window, frame, or device. 97 called @dfn{instantiation}. A domain is a window, frame, or device.
98 98
99 The difference between @dfn{locale} and @dfn{domain} is somewhat subtle. 99 The difference between @dfn{locale} and @dfn{domain} is somewhat subtle.
100 You may think of a locale as a class of domains, which may span 100 You may think of a locale as a class of domains, which may span
101 different devices. Since the specification is abstract (a Lisp form), 101 different devices. Since the specification is abstract (a Lisp form),
102 you can state it without reference to a device. On the other hand, when 102 you can state it without reference to a device. On the other hand, when
197 the other hand, shows you what the programmer (or user) requested. When 197 the other hand, shows you what the programmer (or user) requested. When
198 a program manipulates specifications, clearly it's the latter that is 198 a program manipulates specifications, clearly it's the latter that is
199 desirable. 199 desirable.
200 200
201 In the case of the toolbar descriptor, it turns out that these are the 201 In the case of the toolbar descriptor, it turns out that these are the
202 same: the instancing process is trivial. However, many specifications 202 same: the instantiation process is trivial. However, many specifications
203 have non-trivial instancing. Compare the results of the following forms 203 have non-trivial instantiation. Compare the results of the following forms
204 on my system. (The @samp{(cdr (first ...))} form is due to my use of 204 on my system. (The @samp{(cdr (first ...))} form is due to my use of
205 Mule. On non-Mule XEmacsen, just use @code{specifier-specs}.) 205 Mule. On non-Mule XEmacsen, just use @code{specifier-specs}.)
206 206
207 @example 207 @example
208 (cdr (first (specifier-specs (face-font 'default) 'global))) 208 (cdr (first (specifier-specs (face-font 'default) 'global)))
214 214
215 In this case, @code{specifier-instance} returns an opaque object; 215 In this case, @code{specifier-instance} returns an opaque object;
216 programs can't work on it, they can only pass it around. Worse, in some 216 programs can't work on it, they can only pass it around. Worse, in some
217 environments the instantiation will fail, resulting in a different value 217 environments the instantiation will fail, resulting in a different value
218 (when another instantiation succeeds), or worse yet, an error, if all 218 (when another instantiation succeeds), or worse yet, an error, if all
219 attempts to instance the specifier fail. @code{specifier-instance} is 219 attempts to instantiate the specifier fail. @code{specifier-instance} is
220 context-dependent, even for the exact same specification. 220 context-dependent, even for the exact same specification.
221 @code{specifier-specs} is deterministic, and only depends on the 221 @code{specifier-specs} is deterministic, and only depends on the
222 specifications. 222 specifications.
223 223
224 Note that in the toolbar-changing code we operate in the global locale. 224 Note that in the toolbar-changing code we operate in the global locale.
225 This means that narrower locales, if they have specifications, will 225 This means that narrower locales, if they have specifications, will
226 shadow our changes. (Specifier instancing does not merge 226 shadow our changes. (Specifier instantiation does not merge
227 specifications. It selects the "highest-priority successful 227 specifications. It selects the "highest-priority successful
228 specification" and instances that.) 228 specification" and instantiates that.)
229 229
230 In fact, in our example, it seems pretty likely that different buffers 230 In fact, in our example, it seems pretty likely that different buffers
231 @emph{should} have different buttons. (The icon can be the same, but 231 @emph{should} have different buttons. (The icon can be the same, but
232 the keyboard macro you create in a Dired buffer is highly unlikely to be 232 the keyboard macro you create in a Dired buffer is highly unlikely to be
233 useful in a LaTeX buffer!) Here's one way to implement this: 233 useful in a LaTeX buffer!) Here's one way to implement this:
281 @section In-Depth Overview of a Specifier 281 @section In-Depth Overview of a Specifier
282 @cindex specification (in a specifier) 282 @cindex specification (in a specifier)
283 @cindex domain (in a specifier) 283 @cindex domain (in a specifier)
284 @cindex locale (in a specifier) 284 @cindex locale (in a specifier)
285 @cindex instantiator (in a specifier) 285 @cindex instantiator (in a specifier)
286 @cindex instancing (in a specifier) 286 @cindex instantiation (in a specifier)
287 @cindex instance (in a specifier) 287 @cindex instance (in a specifier)
288 @cindex inst-list (in a specifier) 288 @cindex inst-list (in a specifier)
289 @cindex inst-pair (in a specifier) 289 @cindex inst-pair (in a specifier)
290 @cindex tag (in a specifier) 290 @cindex tag (in a specifier)
291 @cindex tag set (in a specifier) 291 @cindex tag set (in a specifier)
292 @cindex specifier, specification 292 @cindex specifier, specification
293 @cindex specifier, domain 293 @cindex specifier, domain
294 @cindex specifier, locale 294 @cindex specifier, locale
295 @cindex specifier, instantiator 295 @cindex specifier, instantiator
296 @cindex specifier, instancing 296 @cindex specifier, instantiation
297 @cindex specifier, instance 297 @cindex specifier, instance
298 @cindex specifier, inst-list 298 @cindex specifier, inst-list
299 @cindex specifier, inst-pair 299 @cindex specifier, inst-pair
300 @cindex specifier, tag 300 @cindex specifier, tag
301 @cindex specifier, tag set 301 @cindex specifier, tag set
333 Given a specifier, a logical question is ``What is its value in a 333 Given a specifier, a logical question is ``What is its value in a
334 particular situation?'' This involves looking through the specifications 334 particular situation?'' This involves looking through the specifications
335 to see which ones apply to this particular situation, and perhaps 335 to see which ones apply to this particular situation, and perhaps
336 preferring one over another if more than one applies. In specifier 336 preferring one over another if more than one applies. In specifier
337 terminology, a ``particular situation'' is called a @dfn{domain}, and 337 terminology, a ``particular situation'' is called a @dfn{domain}, and
338 determining its value in a particular domain is called @dfn{instancing}. 338 determining its value in a particular domain is called @dfn{instantiation}.
339 Most of the time, a domain is identified by a particular window. For 339 Most of the time, a domain is identified by a particular window. For
340 example, if the redisplay engine is drawing text in the default face in 340 example, if the redisplay engine is drawing text in the default face in
341 a particular window, it retrieves the specifier for the foreground color 341 a particular window, it retrieves the specifier for the foreground color
342 of the default face and @dfn{instances} it in the domain given by that 342 of the default face and @dfn{instantiates} it in the domain given by that
343 window; in other words, it asks the specifier, ``What is your value in 343 window; in other words, it asks the specifier, ``What is your value in
344 this window?''. 344 this window?''.
345 345
346 Note that the redisplay example is in a sense canonical. That is, 346 Note that the redisplay example is in a sense canonical. That is,
347 specifiers are designed to present a uniform and @emph{efficient} API 347 specifiers are designed to present a uniform and @emph{efficient} API
370 device. (If a tag does not have a predicate, it matches all devices.) 370 device. (If a tag does not have a predicate, it matches all devices.)
371 All tags in a tag set must match a device for the associated inst-pair 371 All tags in a tag set must match a device for the associated inst-pair
372 to be instantiable over that device. (A null tag set is perfectly 372 to be instantiable over that device. (A null tag set is perfectly
373 valid, and trivially matches all devices.) 373 valid, and trivially matches all devices.)
374 374
375 @c #### don't we have more device types now, gtk, ms-windows, mac-carbon? 375 The valid device types (normally @code{x}, @code{tty}, @code{stream},
376 The valid device types (normally @code{x}, @code{tty}, and 376 @code{mswindows}, @code{msprinter}, and possibly @code{carbon}) and
377 @code{stream}) and device classes (normally @code{color}, 377 device classes (normally @code{color}, @code{grayscale}, and
378 @code{grayscale}, and @code{mono}) can always be used as tags, and match 378 @code{mono}) can always be used as tags, and match devices of the
379 devices of the associated type or class (@pxref{Consoles and Devices}). 379 associated type or class (@pxref{Consoles and Devices}). User-defined
380 User-defined tags may be defined, with an optional predicate specified. 380 tags may be defined, with an optional predicate specified. An
381 An application can create its own tag, use it to mark all its 381 application can create its own tag, use it to mark all its
382 instantiators, and be fairly confident that it will not interfere with 382 instantiators, and be fairly confident that it will not interfere with
383 other applications that modify the same specifier---Functions that add 383 other applications that modify the same specifier---Functions that add
384 a specification to a specifier usually only overwrite existing 384 a specification to a specifier usually only overwrite existing
385 inst-pairs with the same tag set as was given, and a particular tag or 385 inst-pairs with the same tag set as was given, and a particular tag or
386 tag set can be specified when removing instantiators. 386 tag set can be specified when removing instantiators.
387 387
388 When a specifier is instanced in a domain, both the locale and the tag 388 When a specifier is instantiated in a domain, both the locale and the tag
389 set can be viewed as specifying necessary conditions that must apply in 389 set can be viewed as specifying necessary conditions that must apply in
390 that domain for an instantiator to be considered as a possible result of 390 that domain for an instantiator to be considered as a possible result of
391 the instancing. More specific locales always override more general 391 the instantiation. More specific locales always override more general
392 locales (thus, there is no particular ordering of the specifications in 392 locales (thus, there is no particular ordering of the specifications in
393 a specifier); however, the tag sets are simply considered in the order 393 a specifier); however, the tag sets are simply considered in the order
394 that the inst-pairs occur in the specification's inst-list. 394 that the inst-pairs occur in the specification's inst-list.
395 395
396 Note also that the actual object that results from the instancing 396 Note also that the actual object that results from the instantiation
397 (called an @dfn{instance object}) may not be the same as the instantiator 397 (called an @dfn{instance object}) may not be the same as the instantiator
398 from which it was derived. For some specifier types (such as integer 398 from which it was derived. For some specifier types (such as integer
399 specifiers and boolean specifiers), the instantiator will be returned 399 specifiers and boolean specifiers), the instantiator will be returned
400 directly as the instance object. For other types, however, this 400 directly as the instance object. For other types, however, this
401 is not the case. For example, for font specifiers, the instantiator 401 is not the case. For example, for font specifiers, the instantiator
408 on different devices), the extra properties of that font on that 408 on different devices), the extra properties of that font on that
409 device, etc. Furthermore, this conversion (called @dfn{instantiation}) 409 device, etc. Furthermore, this conversion (called @dfn{instantiation})
410 might fail---a font or color might not exist on a particular device, 410 might fail---a font or color might not exist on a particular device,
411 for example. 411 for example.
412 412
413 @node Specifier Instancing 413 @node Specifier Instantiation
414 @section How a Specifier Is Instanced 414 @section How a Specifier Is Instantiated
415 @cindex fallback (in a specifier) 415 @cindex fallback (in a specifier)
416 @cindex specifier, fallback 416 @cindex specifier, fallback
417 417
418 Instancing of a specifier in a particular window domain proceeds as 418 Instantiation of a specifier in a particular window domain proceeds as
419 follows: 419 follows:
420 420
421 @itemize @bullet 421 @itemize @bullet
422 @item 422 @item
423 First, XEmacs searches for a specification whose locale is the same as 423 First, XEmacs searches for a specification whose locale is the same as
435 match the device.) 435 match the device.)
436 @item 436 @item
437 If a matching tag set is found, the corresponding instantiator is passed 437 If a matching tag set is found, the corresponding instantiator is passed
438 to the specifier's instantiation method, which is specific to the type 438 to the specifier's instantiation method, which is specific to the type
439 of the specifier. If it succeeds, the resulting instance object is 439 of the specifier. If it succeeds, the resulting instance object is
440 returned as the result of the instancing and the instancing is done. 440 returned as the result of the instantiation and the instantiation is done.
441 Otherwise, the operation continues, looking for another matching 441 Otherwise, the operation continues, looking for another matching
442 inst-pair in the current specification. 442 inst-pair in the current specification.
443 @item 443 @item
444 When there are no more inst-pairs to be considered in the current 444 When there are no more inst-pairs to be considered in the current
445 specification, the search starts over, looking for another specification 445 specification, the search starts over, looking for another specification
446 as in the first step above. 446 as in the first step above.
447 @item 447 @item
448 If all specifications are exhausted and no instance object can be 448 If all specifications are exhausted and no instance object can be
449 derived, the instancing fails. (Actually, this is not completely true. 449 derived, the instantiation fails. (Actually, this is not completely true.
450 Some specifier objects for built-in properties have a @dfn{fallback} 450 Some specifier objects for built-in properties have a @dfn{fallback}
451 value, which is either an inst-list or another specifier object, that is 451 value, which is either an inst-list or another specifier object, that is
452 consulted if the instancing is about to fail. If it is an inst-list, 452 consulted if the instantiation is about to fail. If it is an inst-list,
453 the searching proceeds using the inst-pairs in that list. If it is a 453 the searching proceeds using the inst-pairs in that list. If it is a
454 specifier, the entire instancing starts over using that specifier 454 specifier, the entire instantiation starts over using that specifier
455 instead of the given one. Fallback values are set by the C code and 455 instead of the given one. Fallback values are set by the C code and
456 cannot be modified, except perhaps indirectly, using any Lisp functions. 456 cannot be modified, except perhaps indirectly, using any Lisp functions.
457 The purpose of them is to supply some values to make sure that 457 The purpose of them is to supply some values to make sure that
458 instancing of built-in properties can't fail and to implement some basic 458 instantiation of built-in properties can't fail and to implement some basic
459 specifier inheritance, such as the fact that faces inherit their 459 specifier inheritance, such as the fact that faces inherit their
460 properties from the @code{default} face.) 460 properties from the @code{default} face.)
461 @end itemize 461 @end itemize
462 462
463 It is also possible to instance a specifier over a frame domain or 463 It is also possible to instantiate a specifier over a frame domain or
464 device domain instead of over a window domain. The C code, for example, 464 device domain instead of over a window domain. The C code, for example,
465 instances the @code{top-toolbar-height} variable over a frame domain in 465 instantiates the @code{top-toolbar-height} variable over a frame domain in
466 order to determine the height of a frame's top toolbar. Instancing over 466 order to determine the height of a frame's top toolbar. Instantiation over
467 a frame or device is similar to instancing over a window except that 467 a frame or device is similar to instantiation over a window except that
468 specifications for locales that cannot be derived from the domain are 468 specifications for locales that cannot be derived from the domain are
469 ignored. Specifically, instancing over a frame looks first for frame 469 ignored. Specifically, instantiation over a frame looks first for frame
470 locales, then device locales, then the @code{global} locale. Instancing 470 locales, then device locales, then the @code{global} locale. Instantiation
471 over a device domain looks only for device locales and the @code{global} 471 over a device domain looks only for device locales and the @code{global}
472 locale. 472 locale.
473 473
474 Note that specifiers are instanced on @emph{every} redisplay. (This is 474 Note that specifiers are instantiated on @emph{every} redisplay. (This is
475 the concept; of course the implementation keeps track of changes and 475 the concept; of course the implementation keeps track of changes and
476 doesn't reinstance unchanged specifiers.) That means that changes in 476 doesn't reinstantiate unchanged specifiers.) That means that changes in
477 specifiers controlling appearance are reflected immediately in the UI. 477 specifiers controlling appearance are reflected immediately in the UI.
478 Also, since specifiers are instanced completely, removing a 478 Also, since specifiers are instantiated completely, removing a
479 specification can be just as effective as adding one. 479 specification can be just as effective as adding one.
480 480
481 @emph{E.g.}, Giacomo Boffi wanted a modeline that indicates whether the 481 @emph{E.g.}, Giacomo Boffi wanted a modeline that indicates whether the
482 frame containing it is selected or not. The first proposed implementation 482 frame containing it is selected or not. The first proposed implementation
483 is natural in a world of ``local'' variables. The later implementations 483 is natural in a world of ``local'' variables. The later implementations
1107 @end defun 1107 @end defun
1108 1108
1109 @defun specifier-fallback specifier 1109 @defun specifier-fallback specifier
1110 This function returns the fallback value for @var{specifier}. Fallback 1110 This function returns the fallback value for @var{specifier}. Fallback
1111 values are provided by the C code for certain built-in specifiers to 1111 values are provided by the C code for certain built-in specifiers to
1112 make sure that instancing won't fail even if all specs are removed from 1112 make sure that instantiation won't fail even if all specs are removed from
1113 the specifier, or to implement simple inheritance behavior (e.g. this 1113 the specifier, or to implement simple inheritance behavior (e.g. this
1114 method is used to ensure that faces other than @code{default} inherit 1114 method is used to ensure that faces other than @code{default} inherit
1115 their attributes from @code{default}). By design, you cannot change the 1115 their attributes from @code{default}). By design, you cannot change the
1116 fallback value, and specifiers created with @code{make-specifier} will 1116 fallback value, and specifiers created with @code{make-specifier} will
1117 never have a fallback (although a similar, Lisp-accessible capability 1117 never have a fallback (although a similar, Lisp-accessible capability
1118 may be provided in the future to allow for inheritance). 1118 may be provided in the future to allow for inheritance).
1119 1119
1120 The fallback value will be an inst-list that is instanced like 1120 The fallback value will be an inst-list that is instantiated like
1121 any other inst-list, a specifier of the same type as @var{specifier} 1121 any other inst-list, a specifier of the same type as @var{specifier}
1122 (results in inheritance), or @code{nil} for no fallback. 1122 (results in inheritance), or @code{nil} for no fallback.
1123 1123
1124 When you instance a specifier, you can explicitly request that the 1124 When you instantiate a specifier, you can explicitly request that the
1125 fallback not be consulted. (The C code does this, for example, when 1125 fallback not be consulted. (The C code does this, for example, when
1126 merging faces.) See @code{specifier-instance}. 1126 merging faces.) See @code{specifier-instance}.
1127 @end defun 1127 @end defun
1128 1128
1129 @node Specifier Tag Functions 1129 @node Specifier Tag Functions
1143 1143
1144 Each tag has a predicate associated with it, which specifies whether 1144 Each tag has a predicate associated with it, which specifies whether
1145 that tag applies to a particular device. The tags which are device 1145 that tag applies to a particular device. The tags which are device
1146 types and classes match devices of that type or class. User-defined 1146 types and classes match devices of that type or class. User-defined
1147 tags can have any predicate, or none (meaning that all devices match). 1147 tags can have any predicate, or none (meaning that all devices match).
1148 When attempting to instance a specifier, a particular instantiator is 1148 When attempting to instantiate a specifier, a particular instantiator is
1149 only considered if the device of the domain being instanced over matches 1149 only considered if the device of the domain being instantiated over matches
1150 all tags in the tag set attached to that instantiator. 1150 all tags in the tag set attached to that instantiator.
1151 1151
1152 Most of the time, a tag set is not specified, and the instantiator gets 1152 Most of the time, a tag set is not specified, and the instantiator gets
1153 a null tag set, which matches all devices. 1153 a null tag set, which matches all devices.
1154 1154
1199 1199
1200 @defun specifier-tag-predicate tag 1200 @defun specifier-tag-predicate tag
1201 This function returns the predicate for the given specifier tag. 1201 This function returns the predicate for the given specifier tag.
1202 @end defun 1202 @end defun
1203 1203
1204 @node Specifier Instancing Functions 1204 @node Specifier Instantiation Functions
1205 @section Functions for Instancing a Specifier 1205 @section Functions for Instantiating a Specifier
1206 1206
1207 @defun specifier-instance specifier &optional domain default no-fallback 1207 @defun specifier-instance specifier &optional domain default no-fallback
1208 This function instantiates @var{specifier} (returns its value) in 1208 This function instantiates @var{specifier} (returns its value) in
1209 @var{domain}. If no instance can be generated for this domain, return 1209 @var{domain}. If no instance can be generated for this domain, return
1210 @var{default}. 1210 @var{default}.
1603 @node Specifier Validation Functions 1603 @node Specifier Validation Functions
1604 @section Functions for Checking the Validity of Specifier Components 1604 @section Functions for Checking the Validity of Specifier Components
1605 1605
1606 @defun valid-specifier-domain-p domain 1606 @defun valid-specifier-domain-p domain
1607 This function returns non-@code{nil} if @var{domain} is a valid 1607 This function returns non-@code{nil} if @var{domain} is a valid
1608 specifier domain. A domain is used to instance a specifier 1608 specifier domain. A domain is used to instantiate a specifier
1609 (i.e. determine the specifier's value in that domain). Valid domains 1609 (i.e. determine the specifier's value in that domain). Valid domains
1610 are a window, frame, or device. (@code{nil} is not valid.) 1610 are a window, frame, or device. (@code{nil} is not valid.)
1611 @end defun 1611 @end defun
1612 1612
1613 @defun valid-specifier-locale-p locale 1613 @defun valid-specifier-locale-p locale