Mercurial > hg > xemacs-beta
annotate src/objects.c @ 5117:3742ea8250b5 ben-lisp-object ben-lisp-object-final-ws-year-2005
Checking in final CVS version of workspace 'ben-lisp-object'
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 00:20:27 -0600 |
parents | 1e7cc382eb16 |
children | e0db3c197671 |
rev | line source |
---|---|
428 | 1 /* Generic Objects and Functions. |
2 Copyright (C) 1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
2527 | 4 Copyright (C) 1995, 1996, 2002, 2004 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Not in FSF. */ | |
24 | |
25 #include <config.h> | |
26 #include "lisp.h" | |
27 | |
771 | 28 #include "buffer.h" |
872 | 29 #include "device-impl.h" |
428 | 30 #include "elhash.h" |
31 #include "faces.h" | |
32 #include "frame.h" | |
800 | 33 #include "glyphs.h" |
872 | 34 #include "objects-impl.h" |
428 | 35 #include "specifier.h" |
36 #include "window.h" | |
37 | |
1204 | 38 #ifdef HAVE_TTY |
39 #include "console-tty.h" | |
40 #endif | |
934 | 41 |
428 | 42 /* Objects that are substituted when an instantiation fails. |
43 If we leave in the Qunbound value, we will probably get crashes. */ | |
44 Lisp_Object Vthe_null_color_instance, Vthe_null_font_instance; | |
45 | |
46 /* Authors: Ben Wing, Chuck Thompson */ | |
47 | |
2268 | 48 DOESNT_RETURN |
428 | 49 finalose (void *ptr) |
50 { | |
793 | 51 Lisp_Object obj = wrap_pointer_1 (ptr); |
52 | |
563 | 53 invalid_operation |
428 | 54 ("Can't dump an emacs containing window system objects", obj); |
55 } | |
56 | |
57 | |
58 /**************************************************************************** | |
59 * Color-Instance Object * | |
60 ****************************************************************************/ | |
61 | |
62 Lisp_Object Qcolor_instancep; | |
63 | |
1204 | 64 static const struct memory_description color_instance_data_description_1 []= { |
65 #ifdef HAVE_TTY | |
2551 | 66 { XD_BLOCK_PTR, tty_console, 1, { &tty_color_instance_data_description } }, |
1204 | 67 #endif |
934 | 68 { XD_END } |
69 }; | |
70 | |
1204 | 71 static const struct sized_memory_description color_instance_data_description = { |
72 sizeof (void *), color_instance_data_description_1 | |
934 | 73 }; |
74 | |
1204 | 75 static const struct memory_description color_instance_description[] = { |
934 | 76 { XD_INT, offsetof (Lisp_Color_Instance, color_instance_type) }, |
77 { XD_LISP_OBJECT, offsetof (Lisp_Color_Instance, name)}, | |
78 { XD_LISP_OBJECT, offsetof (Lisp_Color_Instance, device)}, | |
1204 | 79 { XD_UNION, offsetof (Lisp_Color_Instance, data), |
2551 | 80 XD_INDIRECT (0, 0), { &color_instance_data_description } }, |
934 | 81 {XD_END} |
82 }; | |
83 | |
428 | 84 static Lisp_Object |
85 mark_color_instance (Lisp_Object obj) | |
86 { | |
440 | 87 Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj); |
428 | 88 mark_object (c->name); |
89 if (!NILP (c->device)) /* Vthe_null_color_instance */ | |
90 MAYBE_DEVMETH (XDEVICE (c->device), mark_color_instance, (c)); | |
91 | |
92 return c->device; | |
93 } | |
94 | |
95 static void | |
96 print_color_instance (Lisp_Object obj, Lisp_Object printcharfun, | |
97 int escapeflag) | |
98 { | |
440 | 99 Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj); |
428 | 100 if (print_readably) |
563 | 101 printing_unreadable_object ("#<color-instance 0x%x>", |
428 | 102 c->header.uid); |
800 | 103 write_fmt_string_lisp (printcharfun, "#<color-instance %s", 1, c->name); |
104 write_fmt_string_lisp (printcharfun, " on %s", 1, c->device); | |
428 | 105 if (!NILP (c->device)) /* Vthe_null_color_instance */ |
106 MAYBE_DEVMETH (XDEVICE (c->device), print_color_instance, | |
107 (c, printcharfun, escapeflag)); | |
800 | 108 write_fmt_string (printcharfun, " 0x%x>", c->header.uid); |
428 | 109 } |
110 | |
111 static void | |
112 finalize_color_instance (void *header, int for_disksave) | |
113 { | |
440 | 114 Lisp_Color_Instance *c = (Lisp_Color_Instance *) header; |
428 | 115 |
116 if (!NILP (c->device)) | |
117 { | |
118 if (for_disksave) finalose (c); | |
119 MAYBE_DEVMETH (XDEVICE (c->device), finalize_color_instance, (c)); | |
120 } | |
121 } | |
122 | |
123 static int | |
124 color_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) | |
125 { | |
440 | 126 Lisp_Color_Instance *c1 = XCOLOR_INSTANCE (obj1); |
127 Lisp_Color_Instance *c2 = XCOLOR_INSTANCE (obj2); | |
428 | 128 |
129 return (c1 == c2) || | |
130 (EQ (c1->device, c2->device) && | |
131 DEVICEP (c1->device) && | |
132 HAS_DEVMETH_P (XDEVICE (c1->device), color_instance_equal) && | |
133 DEVMETH (XDEVICE (c1->device), color_instance_equal, (c1, c2, depth))); | |
134 } | |
135 | |
2515 | 136 static Hashcode |
428 | 137 color_instance_hash (Lisp_Object obj, int depth) |
138 { | |
440 | 139 Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj); |
428 | 140 struct device *d = DEVICEP (c->device) ? XDEVICE (c->device) : 0; |
141 | |
2515 | 142 return HASH2 ((Hashcode) d, |
428 | 143 !d ? LISP_HASH (obj) |
144 : DEVMETH_OR_GIVEN (d, color_instance_hash, (c, depth), | |
145 LISP_HASH (obj))); | |
146 } | |
147 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
148 DEFINE_NONDUMPABLE_LISP_OBJECT ("color-instance", color_instance, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
149 mark_color_instance, print_color_instance, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
150 finalize_color_instance, color_instance_equal, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
151 color_instance_hash, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
152 color_instance_description, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
153 Lisp_Color_Instance); |
428 | 154 |
155 DEFUN ("make-color-instance", Fmake_color_instance, 1, 3, 0, /* | |
156 Return a new `color-instance' object named NAME (a string). | |
157 | |
158 Optional argument DEVICE specifies the device this object applies to | |
159 and defaults to the selected device. | |
160 | |
161 An error is signaled if the color is unknown or cannot be allocated; | |
444 | 162 however, if optional argument NOERROR is non-nil, nil is simply |
163 returned in this case. (And if NOERROR is other than t, a warning may | |
428 | 164 be issued.) |
165 | |
166 The returned object is a normal, first-class lisp object. The way you | |
167 `deallocate' the color is the way you deallocate any other lisp object: | |
168 you drop all pointers to it and allow it to be garbage collected. When | |
169 these objects are GCed, the underlying window-system data (e.g. X object) | |
170 is deallocated as well. | |
171 */ | |
444 | 172 (name, device, noerror)) |
428 | 173 { |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
174 Lisp_Object obj; |
440 | 175 Lisp_Color_Instance *c; |
428 | 176 int retval; |
177 | |
178 CHECK_STRING (name); | |
793 | 179 device = wrap_device (decode_device (device)); |
428 | 180 |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
181 obj = ALLOC_LISP_OBJECT (color_instance); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
182 c = XCOLOR_INSTANCE (obj); |
428 | 183 c->name = name; |
184 c->device = device; | |
185 c->data = 0; | |
1204 | 186 c->color_instance_type = get_console_variant (XDEVICE_TYPE (c->device)); |
428 | 187 |
188 retval = MAYBE_INT_DEVMETH (XDEVICE (device), initialize_color_instance, | |
189 (c, name, device, | |
444 | 190 decode_error_behavior_flag (noerror))); |
428 | 191 if (!retval) |
192 return Qnil; | |
193 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
194 return obj; |
428 | 195 } |
196 | |
197 DEFUN ("color-instance-p", Fcolor_instance_p, 1, 1, 0, /* | |
198 Return non-nil if OBJECT is a color instance. | |
199 */ | |
200 (object)) | |
201 { | |
202 return COLOR_INSTANCEP (object) ? Qt : Qnil; | |
203 } | |
204 | |
205 DEFUN ("color-instance-name", Fcolor_instance_name, 1, 1, 0, /* | |
206 Return the name used to allocate COLOR-INSTANCE. | |
207 */ | |
208 (color_instance)) | |
209 { | |
210 CHECK_COLOR_INSTANCE (color_instance); | |
211 return XCOLOR_INSTANCE (color_instance)->name; | |
212 } | |
213 | |
214 DEFUN ("color-instance-rgb-components", Fcolor_instance_rgb_components, 1, 1, 0, /* | |
215 Return a three element list containing the red, green, and blue | |
216 color components of COLOR-INSTANCE, or nil if unknown. | |
217 Component values range from 0 to 65535. | |
218 */ | |
219 (color_instance)) | |
220 { | |
440 | 221 Lisp_Color_Instance *c; |
428 | 222 |
223 CHECK_COLOR_INSTANCE (color_instance); | |
224 c = XCOLOR_INSTANCE (color_instance); | |
225 | |
226 if (NILP (c->device)) | |
227 return Qnil; | |
228 | |
229 return MAYBE_LISP_DEVMETH (XDEVICE (c->device), | |
230 color_instance_rgb_components, | |
231 (c)); | |
232 } | |
233 | |
234 DEFUN ("valid-color-name-p", Fvalid_color_name_p, 1, 2, 0, /* | |
235 Return true if COLOR names a valid color for the current device. | |
236 | |
237 Valid color names for X are listed in the file /usr/lib/X11/rgb.txt, or | |
238 whatever the equivalent is on your system. | |
239 | |
240 Valid color names for TTY are those which have an ISO 6429 (ANSI) sequence. | |
241 In addition to being a color this may be one of a number of attributes | |
242 such as `blink'. | |
243 */ | |
244 (color, device)) | |
245 { | |
246 struct device *d = decode_device (device); | |
247 | |
248 CHECK_STRING (color); | |
249 return MAYBE_INT_DEVMETH (d, valid_color_name_p, (d, color)) ? Qt : Qnil; | |
250 } | |
251 | |
2527 | 252 DEFUN ("color-list", Fcolor_list, 0, 1, 0, /* |
253 Return a list of color names. | |
254 DEVICE specifies which device to return names for, and defaults to the | |
255 currently selected device. | |
256 */ | |
257 (device)) | |
258 { | |
259 device = wrap_device (decode_device (device)); | |
260 | |
261 return MAYBE_LISP_DEVMETH (XDEVICE (device), color_list, ()); | |
262 } | |
263 | |
428 | 264 |
265 /*************************************************************************** | |
266 * Font-Instance Object * | |
267 ***************************************************************************/ | |
268 | |
269 Lisp_Object Qfont_instancep; | |
270 | |
271 static Lisp_Object font_instance_truename_internal (Lisp_Object xfont, | |
578 | 272 Error_Behavior errb); |
934 | 273 |
1204 | 274 static const struct memory_description font_instance_data_description_1 []= { |
275 #ifdef HAVE_TTY | |
2551 | 276 { XD_BLOCK_PTR, tty_console, 1, { &tty_font_instance_data_description} }, |
1204 | 277 #endif |
934 | 278 { XD_END } |
279 }; | |
280 | |
1204 | 281 static const struct sized_memory_description font_instance_data_description = { |
282 sizeof (void *), font_instance_data_description_1 | |
934 | 283 }; |
284 | |
1204 | 285 static const struct memory_description font_instance_description[] = { |
934 | 286 { XD_INT, offsetof (Lisp_Font_Instance, font_instance_type) }, |
287 { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, name)}, | |
288 { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, truename)}, | |
289 { XD_LISP_OBJECT, offsetof (Lisp_Font_Instance, device)}, | |
290 { XD_UNION, offsetof (Lisp_Font_Instance, data), | |
2551 | 291 XD_INDIRECT (0, 0), { &font_instance_data_description } }, |
1204 | 292 { XD_END } |
934 | 293 }; |
294 | |
428 | 295 |
296 static Lisp_Object | |
297 mark_font_instance (Lisp_Object obj) | |
298 { | |
440 | 299 Lisp_Font_Instance *f = XFONT_INSTANCE (obj); |
428 | 300 |
301 mark_object (f->name); | |
872 | 302 mark_object (f->truename); |
428 | 303 if (!NILP (f->device)) /* Vthe_null_font_instance */ |
304 MAYBE_DEVMETH (XDEVICE (f->device), mark_font_instance, (f)); | |
305 | |
306 return f->device; | |
307 } | |
308 | |
309 static void | |
310 print_font_instance (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
311 { | |
440 | 312 Lisp_Font_Instance *f = XFONT_INSTANCE (obj); |
428 | 313 if (print_readably) |
563 | 314 printing_unreadable_object ("#<font-instance 0x%x>", f->header.uid); |
800 | 315 write_fmt_string_lisp (printcharfun, "#<font-instance %S", 1, f->name); |
316 write_fmt_string_lisp (printcharfun, " on %s", 1, f->device); | |
428 | 317 if (!NILP (f->device)) |
318 MAYBE_DEVMETH (XDEVICE (f->device), print_font_instance, | |
319 (f, printcharfun, escapeflag)); | |
800 | 320 write_fmt_string (printcharfun, " 0x%x>", f->header.uid); |
428 | 321 } |
322 | |
323 static void | |
324 finalize_font_instance (void *header, int for_disksave) | |
325 { | |
440 | 326 Lisp_Font_Instance *f = (Lisp_Font_Instance *) header; |
428 | 327 |
328 if (!NILP (f->device)) | |
329 { | |
330 if (for_disksave) finalose (f); | |
331 MAYBE_DEVMETH (XDEVICE (f->device), finalize_font_instance, (f)); | |
332 } | |
333 } | |
334 | |
335 /* Fonts are equal if they resolve to the same name. | |
336 Since we call `font-truename' to do this, and since font-truename is lazy, | |
337 this means the `equal' could cause XListFonts to be run the first time. | |
338 */ | |
339 static int | |
340 font_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) | |
341 { | |
342 /* #### should this be moved into a device method? */ | |
793 | 343 return internal_equal (font_instance_truename_internal |
344 (obj1, ERROR_ME_DEBUG_WARN), | |
345 font_instance_truename_internal | |
346 (obj2, ERROR_ME_DEBUG_WARN), | |
428 | 347 depth + 1); |
348 } | |
349 | |
2515 | 350 static Hashcode |
428 | 351 font_instance_hash (Lisp_Object obj, int depth) |
352 { | |
793 | 353 return internal_hash (font_instance_truename_internal |
354 (obj, ERROR_ME_DEBUG_WARN), | |
428 | 355 depth + 1); |
356 } | |
357 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
358 DEFINE_NONDUMPABLE_LISP_OBJECT ("font-instance", font_instance, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
359 mark_font_instance, print_font_instance, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
360 finalize_font_instance, font_instance_equal, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
361 font_instance_hash, font_instance_description, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
362 Lisp_Font_Instance); |
934 | 363 |
428 | 364 |
365 DEFUN ("make-font-instance", Fmake_font_instance, 1, 3, 0, /* | |
366 Return a new `font-instance' object named NAME. | |
367 DEVICE specifies the device this object applies to and defaults to the | |
368 selected device. An error is signalled if the font is unknown or cannot | |
369 be allocated; however, if NOERROR is non-nil, nil is simply returned in | |
370 this case. | |
371 | |
372 The returned object is a normal, first-class lisp object. The way you | |
373 `deallocate' the font is the way you deallocate any other lisp object: | |
374 you drop all pointers to it and allow it to be garbage collected. When | |
375 these objects are GCed, the underlying X data is deallocated as well. | |
376 */ | |
444 | 377 (name, device, noerror)) |
428 | 378 { |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
379 Lisp_Object obj; |
440 | 380 Lisp_Font_Instance *f; |
428 | 381 int retval = 0; |
578 | 382 Error_Behavior errb = decode_error_behavior_flag (noerror); |
428 | 383 |
384 if (ERRB_EQ (errb, ERROR_ME)) | |
385 CHECK_STRING (name); | |
386 else if (!STRINGP (name)) | |
387 return Qnil; | |
388 | |
793 | 389 device = wrap_device (decode_device (device)); |
428 | 390 |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
391 obj = ALLOC_LISP_OBJECT (font_instance); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
392 f = XFONT_INSTANCE (obj); |
428 | 393 f->name = name; |
872 | 394 f->truename = Qnil; |
428 | 395 f->device = device; |
396 | |
397 f->data = 0; | |
1204 | 398 f->font_instance_type = get_console_variant (XDEVICE_TYPE (f->device)); |
428 | 399 |
400 /* Stick some default values here ... */ | |
401 f->ascent = f->height = 1; | |
402 f->descent = 0; | |
403 f->width = 1; | |
404 f->proportional_p = 0; | |
405 | |
406 retval = MAYBE_INT_DEVMETH (XDEVICE (device), initialize_font_instance, | |
407 (f, name, device, errb)); | |
408 | |
409 if (!retval) | |
410 return Qnil; | |
411 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
412 return obj; |
428 | 413 } |
414 | |
415 DEFUN ("font-instance-p", Ffont_instance_p, 1, 1, 0, /* | |
416 Return non-nil if OBJECT is a font instance. | |
417 */ | |
418 (object)) | |
419 { | |
420 return FONT_INSTANCEP (object) ? Qt : Qnil; | |
421 } | |
422 | |
423 DEFUN ("font-instance-name", Ffont_instance_name, 1, 1, 0, /* | |
424 Return the name used to allocate FONT-INSTANCE. | |
425 */ | |
426 (font_instance)) | |
427 { | |
428 CHECK_FONT_INSTANCE (font_instance); | |
429 return XFONT_INSTANCE (font_instance)->name; | |
430 } | |
431 | |
432 DEFUN ("font-instance-ascent", Ffont_instance_ascent, 1, 1, 0, /* | |
433 Return the ascent in pixels of FONT-INSTANCE. | |
434 The returned value is the maximum ascent for all characters in the font, | |
435 where a character's ascent is the number of pixels above (and including) | |
436 the baseline. | |
437 */ | |
438 (font_instance)) | |
439 { | |
440 CHECK_FONT_INSTANCE (font_instance); | |
441 return make_int (XFONT_INSTANCE (font_instance)->ascent); | |
442 } | |
443 | |
444 DEFUN ("font-instance-descent", Ffont_instance_descent, 1, 1, 0, /* | |
445 Return the descent in pixels of FONT-INSTANCE. | |
446 The returned value is the maximum descent for all characters in the font, | |
447 where a character's descent is the number of pixels below the baseline. | |
448 \(Many characters to do not have any descent. Typical characters with a | |
449 descent are lowercase p and lowercase g.) | |
450 */ | |
451 (font_instance)) | |
452 { | |
453 CHECK_FONT_INSTANCE (font_instance); | |
454 return make_int (XFONT_INSTANCE (font_instance)->descent); | |
455 } | |
456 | |
457 DEFUN ("font-instance-width", Ffont_instance_width, 1, 1, 0, /* | |
458 Return the width in pixels of FONT-INSTANCE. | |
459 The returned value is the average width for all characters in the font. | |
460 */ | |
461 (font_instance)) | |
462 { | |
463 CHECK_FONT_INSTANCE (font_instance); | |
464 return make_int (XFONT_INSTANCE (font_instance)->width); | |
465 } | |
466 | |
467 DEFUN ("font-instance-proportional-p", Ffont_instance_proportional_p, 1, 1, 0, /* | |
468 Return whether FONT-INSTANCE is proportional. | |
469 This means that different characters in the font have different widths. | |
470 */ | |
471 (font_instance)) | |
472 { | |
473 CHECK_FONT_INSTANCE (font_instance); | |
474 return XFONT_INSTANCE (font_instance)->proportional_p ? Qt : Qnil; | |
475 } | |
476 | |
477 static Lisp_Object | |
478 font_instance_truename_internal (Lisp_Object font_instance, | |
578 | 479 Error_Behavior errb) |
428 | 480 { |
440 | 481 Lisp_Font_Instance *f = XFONT_INSTANCE (font_instance); |
482 | |
428 | 483 if (NILP (f->device)) |
484 { | |
563 | 485 maybe_signal_error (Qgui_error, "Couldn't determine font truename", |
486 font_instance, Qfont, errb); | |
428 | 487 return Qnil; |
488 } | |
440 | 489 |
428 | 490 return DEVMETH_OR_GIVEN (XDEVICE (f->device), |
491 font_instance_truename, (f, errb), f->name); | |
492 } | |
493 | |
494 DEFUN ("font-instance-truename", Ffont_instance_truename, 1, 1, 0, /* | |
495 Return the canonical name of FONT-INSTANCE. | |
496 Font names are patterns which may match any number of fonts, of which | |
497 the first found is used. This returns an unambiguous name for that font | |
498 \(but not necessarily its only unambiguous name). | |
499 */ | |
500 (font_instance)) | |
501 { | |
502 CHECK_FONT_INSTANCE (font_instance); | |
503 return font_instance_truename_internal (font_instance, ERROR_ME); | |
504 } | |
505 | |
506 DEFUN ("font-instance-properties", Ffont_instance_properties, 1, 1, 0, /* | |
507 Return the properties (an alist or nil) of FONT-INSTANCE. | |
508 */ | |
509 (font_instance)) | |
510 { | |
440 | 511 Lisp_Font_Instance *f; |
428 | 512 |
513 CHECK_FONT_INSTANCE (font_instance); | |
514 f = XFONT_INSTANCE (font_instance); | |
515 | |
516 if (NILP (f->device)) | |
517 return Qnil; | |
518 | |
519 return MAYBE_LISP_DEVMETH (XDEVICE (f->device), | |
520 font_instance_properties, (f)); | |
521 } | |
522 | |
2527 | 523 DEFUN ("font-list", Ffont_list, 1, 3, 0, /* |
428 | 524 Return a list of font names matching the given pattern. |
525 DEVICE specifies which device to search for names, and defaults to the | |
526 currently selected device. | |
527 */ | |
1701 | 528 (pattern, device, maxnumber)) |
428 | 529 { |
530 CHECK_STRING (pattern); | |
793 | 531 device = wrap_device (decode_device (device)); |
428 | 532 |
2527 | 533 return MAYBE_LISP_DEVMETH (XDEVICE (device), font_list, (pattern, device, |
1701 | 534 maxnumber)); |
428 | 535 } |
536 | |
537 | |
538 /**************************************************************************** | |
539 Color Object | |
540 ***************************************************************************/ | |
1204 | 541 |
542 static const struct memory_description color_specifier_description[] = { | |
543 { XD_LISP_OBJECT, offsetof (struct color_specifier, face) }, | |
544 { XD_LISP_OBJECT, offsetof (struct color_specifier, face_property) }, | |
545 { XD_END } | |
546 }; | |
547 | |
548 DEFINE_SPECIFIER_TYPE_WITH_DATA (color); | |
428 | 549 /* Qcolor defined in general.c */ |
550 | |
551 static void | |
552 color_create (Lisp_Object obj) | |
553 { | |
440 | 554 Lisp_Specifier *color = XCOLOR_SPECIFIER (obj); |
428 | 555 |
556 COLOR_SPECIFIER_FACE (color) = Qnil; | |
557 COLOR_SPECIFIER_FACE_PROPERTY (color) = Qnil; | |
558 } | |
559 | |
560 static void | |
561 color_mark (Lisp_Object obj) | |
562 { | |
440 | 563 Lisp_Specifier *color = XCOLOR_SPECIFIER (obj); |
428 | 564 |
565 mark_object (COLOR_SPECIFIER_FACE (color)); | |
566 mark_object (COLOR_SPECIFIER_FACE_PROPERTY (color)); | |
567 } | |
568 | |
569 /* No equal or hash methods; ignore the face the color is based off | |
570 of for `equal' */ | |
571 | |
572 static Lisp_Object | |
2286 | 573 color_instantiate (Lisp_Object specifier, Lisp_Object UNUSED (matchspec), |
428 | 574 Lisp_Object domain, Lisp_Object instantiator, |
575 Lisp_Object depth) | |
576 { | |
577 /* When called, we're inside of call_with_suspended_errors(), | |
578 so we can freely error. */ | |
442 | 579 Lisp_Object device = DOMAIN_DEVICE (domain); |
428 | 580 struct device *d = XDEVICE (device); |
581 | |
582 if (COLOR_INSTANCEP (instantiator)) | |
583 { | |
584 /* If we are on the same device then we're done. Otherwise change | |
585 the instantiator to the name used to generate the pixel and let the | |
586 STRINGP case deal with it. */ | |
587 if (NILP (device) /* Vthe_null_color_instance */ | |
588 || EQ (device, XCOLOR_INSTANCE (instantiator)->device)) | |
589 return instantiator; | |
590 else | |
591 instantiator = Fcolor_instance_name (instantiator); | |
592 } | |
593 | |
594 if (STRINGP (instantiator)) | |
595 { | |
596 /* First, look to see if we can retrieve a cached value. */ | |
597 Lisp_Object instance = | |
598 Fgethash (instantiator, d->color_instance_cache, Qunbound); | |
599 /* Otherwise, make a new one. */ | |
600 if (UNBOUNDP (instance)) | |
601 { | |
602 /* make sure we cache the failures, too. */ | |
603 instance = Fmake_color_instance (instantiator, device, Qt); | |
604 Fputhash (instantiator, instance, d->color_instance_cache); | |
605 } | |
606 | |
607 return NILP (instance) ? Qunbound : instance; | |
608 } | |
609 else if (VECTORP (instantiator)) | |
610 { | |
611 switch (XVECTOR_LENGTH (instantiator)) | |
612 { | |
613 case 0: | |
614 if (DEVICE_TTY_P (d)) | |
615 return Vthe_null_color_instance; | |
616 else | |
563 | 617 gui_error ("Color instantiator [] only valid on TTY's", |
428 | 618 device); |
619 | |
620 case 1: | |
621 if (NILP (COLOR_SPECIFIER_FACE (XCOLOR_SPECIFIER (specifier)))) | |
563 | 622 gui_error ("Color specifier not attached to a face", |
428 | 623 instantiator); |
624 return (FACE_PROPERTY_INSTANCE_1 | |
625 (Fget_face (XVECTOR_DATA (instantiator)[0]), | |
626 COLOR_SPECIFIER_FACE_PROPERTY (XCOLOR_SPECIFIER (specifier)), | |
627 domain, ERROR_ME, 0, depth)); | |
628 | |
629 case 2: | |
630 return (FACE_PROPERTY_INSTANCE_1 | |
631 (Fget_face (XVECTOR_DATA (instantiator)[0]), | |
632 XVECTOR_DATA (instantiator)[1], domain, ERROR_ME, 0, depth)); | |
633 | |
634 default: | |
2500 | 635 ABORT (); |
428 | 636 } |
637 } | |
638 else if (NILP (instantiator)) | |
639 { | |
640 if (DEVICE_TTY_P (d)) | |
641 return Vthe_null_color_instance; | |
642 else | |
563 | 643 gui_error ("Color instantiator [] only valid on TTY's", |
428 | 644 device); |
645 } | |
646 else | |
2500 | 647 ABORT (); /* The spec validation routines are screwed up. */ |
428 | 648 |
649 return Qunbound; | |
650 } | |
651 | |
652 static void | |
653 color_validate (Lisp_Object instantiator) | |
654 { | |
655 if (COLOR_INSTANCEP (instantiator) || STRINGP (instantiator)) | |
656 return; | |
657 if (VECTORP (instantiator)) | |
658 { | |
659 if (XVECTOR_LENGTH (instantiator) > 2) | |
563 | 660 sferror ("Inheritance vector must be of size 0 - 2", |
428 | 661 instantiator); |
662 else if (XVECTOR_LENGTH (instantiator) > 0) | |
663 { | |
664 Lisp_Object face = XVECTOR_DATA (instantiator)[0]; | |
665 | |
666 Fget_face (face); | |
667 if (XVECTOR_LENGTH (instantiator) == 2) | |
668 { | |
669 Lisp_Object field = XVECTOR_DATA (instantiator)[1]; | |
670 if (!EQ (field, Qforeground) && !EQ (field, Qbackground)) | |
563 | 671 invalid_constant |
428 | 672 ("Inheritance field must be `foreground' or `background'", |
673 field); | |
674 } | |
675 } | |
676 } | |
677 else | |
563 | 678 invalid_argument ("Invalid color instantiator", instantiator); |
428 | 679 } |
680 | |
681 static void | |
682 color_after_change (Lisp_Object specifier, Lisp_Object locale) | |
683 { | |
684 Lisp_Object face = COLOR_SPECIFIER_FACE (XCOLOR_SPECIFIER (specifier)); | |
685 Lisp_Object property = | |
686 COLOR_SPECIFIER_FACE_PROPERTY (XCOLOR_SPECIFIER (specifier)); | |
687 if (!NILP (face)) | |
448 | 688 { |
689 face_property_was_changed (face, property, locale); | |
690 if (BUFFERP (locale)) | |
691 XBUFFER (locale)->buffer_local_face_property = 1; | |
692 } | |
428 | 693 } |
694 | |
695 void | |
696 set_color_attached_to (Lisp_Object obj, Lisp_Object face, Lisp_Object property) | |
697 { | |
440 | 698 Lisp_Specifier *color = XCOLOR_SPECIFIER (obj); |
428 | 699 |
700 COLOR_SPECIFIER_FACE (color) = face; | |
701 COLOR_SPECIFIER_FACE_PROPERTY (color) = property; | |
702 } | |
703 | |
704 DEFUN ("color-specifier-p", Fcolor_specifier_p, 1, 1, 0, /* | |
705 Return t if OBJECT is a color specifier. | |
706 | |
442 | 707 See `make-color-specifier' for a description of possible color instantiators. |
428 | 708 */ |
709 (object)) | |
710 { | |
711 return COLOR_SPECIFIERP (object) ? Qt : Qnil; | |
712 } | |
713 | |
714 | |
715 /**************************************************************************** | |
716 Font Object | |
717 ***************************************************************************/ | |
1204 | 718 |
719 static const struct memory_description font_specifier_description[] = { | |
720 { XD_LISP_OBJECT, offsetof (struct font_specifier, face) }, | |
721 { XD_LISP_OBJECT, offsetof (struct font_specifier, face_property) }, | |
722 { XD_END } | |
723 }; | |
724 | |
725 DEFINE_SPECIFIER_TYPE_WITH_DATA (font); | |
428 | 726 /* Qfont defined in general.c */ |
727 | |
728 static void | |
729 font_create (Lisp_Object obj) | |
730 { | |
440 | 731 Lisp_Specifier *font = XFONT_SPECIFIER (obj); |
428 | 732 |
733 FONT_SPECIFIER_FACE (font) = Qnil; | |
734 FONT_SPECIFIER_FACE_PROPERTY (font) = Qnil; | |
735 } | |
736 | |
737 static void | |
738 font_mark (Lisp_Object obj) | |
739 { | |
440 | 740 Lisp_Specifier *font = XFONT_SPECIFIER (obj); |
428 | 741 |
742 mark_object (FONT_SPECIFIER_FACE (font)); | |
743 mark_object (FONT_SPECIFIER_FACE_PROPERTY (font)); | |
744 } | |
745 | |
746 /* No equal or hash methods; ignore the face the font is based off | |
747 of for `equal' */ | |
748 | |
749 #ifdef MULE | |
750 | |
872 | 751 /* Given a truename font spec (i.e. the font spec should have its registry |
752 field filled in), does it support displaying characters from CHARSET? */ | |
753 | |
754 static int | |
428 | 755 font_spec_matches_charset (struct device *d, Lisp_Object charset, |
867 | 756 const Ibyte *nonreloc, Lisp_Object reloc, |
872 | 757 Bytecount offset, Bytecount length, |
758 int stage) | |
428 | 759 { |
760 return DEVMETH_OR_GIVEN (d, font_spec_matches_charset, | |
872 | 761 (d, charset, nonreloc, reloc, offset, length, |
762 stage), | |
428 | 763 1); |
764 } | |
765 | |
766 static void | |
767 font_validate_matchspec (Lisp_Object matchspec) | |
768 { | |
872 | 769 CHECK_CONS (matchspec); |
770 Fget_charset (XCAR (matchspec)); | |
428 | 771 } |
772 | |
872 | 773 void |
774 initialize_charset_font_caches (struct device *d) | |
775 { | |
776 /* Note that the following tables are bi-level. */ | |
777 d->charset_font_cache_stage_1 = | |
778 make_lisp_hash_table (20, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | |
779 d->charset_font_cache_stage_2 = | |
780 make_lisp_hash_table (20, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); | |
781 } | |
782 | |
783 void | |
784 invalidate_charset_font_caches (Lisp_Object charset) | |
785 { | |
786 /* Invalidate font cache entries for charset on all devices. */ | |
787 Lisp_Object devcons, concons, hash_table; | |
788 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
789 { | |
790 struct device *d = XDEVICE (XCAR (devcons)); | |
791 hash_table = Fgethash (charset, d->charset_font_cache_stage_1, | |
792 Qunbound); | |
793 if (!UNBOUNDP (hash_table)) | |
794 Fclrhash (hash_table); | |
795 hash_table = Fgethash (charset, d->charset_font_cache_stage_2, | |
796 Qunbound); | |
797 if (!UNBOUNDP (hash_table)) | |
798 Fclrhash (hash_table); | |
799 } | |
800 } | |
428 | 801 |
874 | 802 #endif /* MULE */ |
803 | |
804 | |
428 | 805 static Lisp_Object |
2333 | 806 font_instantiate (Lisp_Object UNUSED (specifier), |
807 Lisp_Object USED_IF_MULE (matchspec), | |
428 | 808 Lisp_Object domain, Lisp_Object instantiator, |
809 Lisp_Object depth) | |
810 { | |
811 /* When called, we're inside of call_with_suspended_errors(), | |
812 so we can freely error. */ | |
442 | 813 Lisp_Object device = DOMAIN_DEVICE (domain); |
428 | 814 struct device *d = XDEVICE (device); |
815 Lisp_Object instance; | |
872 | 816 Lisp_Object charset = Qnil; |
1204 | 817 #ifdef MULE |
872 | 818 int stage = 0; |
428 | 819 |
820 if (!UNBOUNDP (matchspec)) | |
872 | 821 { |
822 charset = Fget_charset (XCAR (matchspec)); | |
823 stage = NILP (XCDR (matchspec)) ? 0 : 1; | |
824 } | |
428 | 825 #endif |
826 | |
827 if (FONT_INSTANCEP (instantiator)) | |
828 { | |
829 if (NILP (device) | |
830 || EQ (device, XFONT_INSTANCE (instantiator)->device)) | |
831 { | |
832 #ifdef MULE | |
872 | 833 if (font_spec_matches_charset (d, charset, 0, |
428 | 834 Ffont_instance_truename |
835 (instantiator), | |
872 | 836 0, -1, stage)) |
1204 | 837 #endif |
428 | 838 return instantiator; |
839 } | |
840 instantiator = Ffont_instance_name (instantiator); | |
841 } | |
842 | |
843 if (STRINGP (instantiator)) | |
844 { | |
874 | 845 #ifdef MULE |
872 | 846 Lisp_Object cache = stage ? d->charset_font_cache_stage_2 : |
847 d->charset_font_cache_stage_1; | |
874 | 848 #else |
849 Lisp_Object cache = d->font_instance_cache; | |
850 #endif | |
872 | 851 |
428 | 852 #ifdef MULE |
872 | 853 if (!NILP (charset)) |
428 | 854 { |
855 /* The instantiator is a font spec that could match many | |
856 different fonts. We need to find one of those fonts | |
857 whose registry matches the registry of the charset in | |
858 MATCHSPEC. This is potentially a very slow operation, | |
859 as it involves doing an XListFonts() or equivalent to | |
860 iterate over all possible fonts, and a regexp match | |
861 on each one. So we cache the results. */ | |
862 Lisp_Object matching_font = Qunbound; | |
872 | 863 Lisp_Object hash_table = Fgethash (charset, cache, Qunbound); |
428 | 864 if (UNBOUNDP (hash_table)) |
865 { | |
866 /* need to make a sub hash table. */ | |
867 hash_table = make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, | |
868 HASH_TABLE_EQUAL); | |
872 | 869 Fputhash (charset, hash_table, cache); |
428 | 870 } |
871 else | |
872 matching_font = Fgethash (instantiator, hash_table, Qunbound); | |
873 | |
874 if (UNBOUNDP (matching_font)) | |
875 { | |
876 /* make sure we cache the failures, too. */ | |
877 matching_font = | |
878 DEVMETH_OR_GIVEN (d, find_charset_font, | |
872 | 879 (device, instantiator, charset, stage), |
428 | 880 instantiator); |
881 Fputhash (instantiator, matching_font, hash_table); | |
882 } | |
883 if (NILP (matching_font)) | |
884 return Qunbound; | |
885 instantiator = matching_font; | |
886 } | |
887 #endif /* MULE */ | |
888 | |
889 /* First, look to see if we can retrieve a cached value. */ | |
872 | 890 instance = Fgethash (instantiator, cache, Qunbound); |
428 | 891 /* Otherwise, make a new one. */ |
892 if (UNBOUNDP (instance)) | |
893 { | |
894 /* make sure we cache the failures, too. */ | |
895 instance = Fmake_font_instance (instantiator, device, Qt); | |
872 | 896 Fputhash (instantiator, instance, cache); |
428 | 897 } |
898 | |
899 return NILP (instance) ? Qunbound : instance; | |
900 } | |
901 else if (VECTORP (instantiator)) | |
902 { | |
903 assert (XVECTOR_LENGTH (instantiator) == 1); | |
904 return (face_property_matching_instance | |
905 (Fget_face (XVECTOR_DATA (instantiator)[0]), Qfont, | |
872 | 906 charset, domain, ERROR_ME, 0, depth)); |
428 | 907 } |
908 else if (NILP (instantiator)) | |
909 return Qunbound; | |
910 else | |
2500 | 911 ABORT (); /* Eh? */ |
428 | 912 |
913 return Qunbound; | |
914 } | |
915 | |
916 static void | |
917 font_validate (Lisp_Object instantiator) | |
918 { | |
919 if (FONT_INSTANCEP (instantiator) || STRINGP (instantiator)) | |
920 return; | |
921 if (VECTORP (instantiator)) | |
922 { | |
923 if (XVECTOR_LENGTH (instantiator) != 1) | |
924 { | |
563 | 925 sferror |
428 | 926 ("Vector length must be one for font inheritance", instantiator); |
927 } | |
928 Fget_face (XVECTOR_DATA (instantiator)[0]); | |
929 } | |
930 else | |
563 | 931 invalid_argument ("Must be string, vector, or font-instance", |
428 | 932 instantiator); |
933 } | |
934 | |
935 static void | |
936 font_after_change (Lisp_Object specifier, Lisp_Object locale) | |
937 { | |
938 Lisp_Object face = FONT_SPECIFIER_FACE (XFONT_SPECIFIER (specifier)); | |
939 Lisp_Object property = | |
940 FONT_SPECIFIER_FACE_PROPERTY (XFONT_SPECIFIER (specifier)); | |
941 if (!NILP (face)) | |
448 | 942 { |
943 face_property_was_changed (face, property, locale); | |
944 if (BUFFERP (locale)) | |
945 XBUFFER (locale)->buffer_local_face_property = 1; | |
946 } | |
428 | 947 } |
948 | |
949 void | |
950 set_font_attached_to (Lisp_Object obj, Lisp_Object face, Lisp_Object property) | |
951 { | |
440 | 952 Lisp_Specifier *font = XFONT_SPECIFIER (obj); |
428 | 953 |
954 FONT_SPECIFIER_FACE (font) = face; | |
955 FONT_SPECIFIER_FACE_PROPERTY (font) = property; | |
956 } | |
957 | |
958 DEFUN ("font-specifier-p", Ffont_specifier_p, 1, 1, 0, /* | |
959 Return non-nil if OBJECT is a font specifier. | |
960 | |
442 | 961 See `make-font-specifier' for a description of possible font instantiators. |
428 | 962 */ |
963 (object)) | |
964 { | |
965 return FONT_SPECIFIERP (object) ? Qt : Qnil; | |
966 } | |
967 | |
968 | |
969 /***************************************************************************** | |
970 Face Boolean Object | |
971 ****************************************************************************/ | |
1204 | 972 |
973 static const struct memory_description face_boolean_specifier_description[] = { | |
974 { XD_LISP_OBJECT, offsetof (struct face_boolean_specifier, face) }, | |
975 { XD_LISP_OBJECT, offsetof (struct face_boolean_specifier, face_property) }, | |
976 { XD_END } | |
977 }; | |
978 | |
979 DEFINE_SPECIFIER_TYPE_WITH_DATA (face_boolean); | |
428 | 980 Lisp_Object Qface_boolean; |
981 | |
982 static void | |
983 face_boolean_create (Lisp_Object obj) | |
984 { | |
440 | 985 Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj); |
428 | 986 |
987 FACE_BOOLEAN_SPECIFIER_FACE (face_boolean) = Qnil; | |
988 FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean) = Qnil; | |
989 } | |
990 | |
991 static void | |
992 face_boolean_mark (Lisp_Object obj) | |
993 { | |
440 | 994 Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj); |
428 | 995 |
996 mark_object (FACE_BOOLEAN_SPECIFIER_FACE (face_boolean)); | |
997 mark_object (FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean)); | |
998 } | |
999 | |
1000 /* No equal or hash methods; ignore the face the face-boolean is based off | |
1001 of for `equal' */ | |
1002 | |
1003 static Lisp_Object | |
2286 | 1004 face_boolean_instantiate (Lisp_Object specifier, |
1005 Lisp_Object UNUSED (matchspec), | |
428 | 1006 Lisp_Object domain, Lisp_Object instantiator, |
1007 Lisp_Object depth) | |
1008 { | |
1009 /* When called, we're inside of call_with_suspended_errors(), | |
1010 so we can freely error. */ | |
1011 if (NILP (instantiator) || EQ (instantiator, Qt)) | |
1012 return instantiator; | |
1013 else if (VECTORP (instantiator)) | |
1014 { | |
1015 Lisp_Object retval; | |
1016 Lisp_Object prop; | |
1017 int instantiator_len = XVECTOR_LENGTH (instantiator); | |
1018 | |
1019 assert (instantiator_len >= 1 && instantiator_len <= 3); | |
1020 if (instantiator_len > 1) | |
1021 prop = XVECTOR_DATA (instantiator)[1]; | |
1022 else | |
1023 { | |
1024 if (NILP (FACE_BOOLEAN_SPECIFIER_FACE | |
1025 (XFACE_BOOLEAN_SPECIFIER (specifier)))) | |
563 | 1026 gui_error |
428 | 1027 ("Face-boolean specifier not attached to a face", instantiator); |
1028 prop = FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY | |
1029 (XFACE_BOOLEAN_SPECIFIER (specifier)); | |
1030 } | |
1031 | |
1032 retval = (FACE_PROPERTY_INSTANCE_1 | |
1033 (Fget_face (XVECTOR_DATA (instantiator)[0]), | |
1034 prop, domain, ERROR_ME, 0, depth)); | |
1035 | |
1036 if (instantiator_len == 3 && !NILP (XVECTOR_DATA (instantiator)[2])) | |
1037 retval = NILP (retval) ? Qt : Qnil; | |
1038 | |
1039 return retval; | |
1040 } | |
1041 else | |
2500 | 1042 ABORT (); /* Eh? */ |
428 | 1043 |
1044 return Qunbound; | |
1045 } | |
1046 | |
1047 static void | |
1048 face_boolean_validate (Lisp_Object instantiator) | |
1049 { | |
1050 if (NILP (instantiator) || EQ (instantiator, Qt)) | |
1051 return; | |
1052 else if (VECTORP (instantiator) && | |
1053 (XVECTOR_LENGTH (instantiator) >= 1 && | |
1054 XVECTOR_LENGTH (instantiator) <= 3)) | |
1055 { | |
1056 Lisp_Object face = XVECTOR_DATA (instantiator)[0]; | |
1057 | |
1058 Fget_face (face); | |
1059 | |
1060 if (XVECTOR_LENGTH (instantiator) > 1) | |
1061 { | |
1062 Lisp_Object field = XVECTOR_DATA (instantiator)[1]; | |
1063 if (!EQ (field, Qunderline) | |
1064 && !EQ (field, Qstrikethru) | |
1065 && !EQ (field, Qhighlight) | |
1066 && !EQ (field, Qdim) | |
1067 && !EQ (field, Qblinking) | |
1068 && !EQ (field, Qreverse)) | |
563 | 1069 invalid_constant ("Invalid face-boolean inheritance field", |
428 | 1070 field); |
1071 } | |
1072 } | |
1073 else if (VECTORP (instantiator)) | |
563 | 1074 sferror ("Wrong length for face-boolean inheritance spec", |
428 | 1075 instantiator); |
1076 else | |
563 | 1077 invalid_argument ("Face-boolean instantiator must be nil, t, or vector", |
428 | 1078 instantiator); |
1079 } | |
1080 | |
1081 static void | |
1082 face_boolean_after_change (Lisp_Object specifier, Lisp_Object locale) | |
1083 { | |
1084 Lisp_Object face = | |
1085 FACE_BOOLEAN_SPECIFIER_FACE (XFACE_BOOLEAN_SPECIFIER (specifier)); | |
1086 Lisp_Object property = | |
1087 FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (XFACE_BOOLEAN_SPECIFIER (specifier)); | |
1088 if (!NILP (face)) | |
448 | 1089 { |
1090 face_property_was_changed (face, property, locale); | |
1091 if (BUFFERP (locale)) | |
1092 XBUFFER (locale)->buffer_local_face_property = 1; | |
1093 } | |
428 | 1094 } |
1095 | |
1096 void | |
1097 set_face_boolean_attached_to (Lisp_Object obj, Lisp_Object face, | |
1098 Lisp_Object property) | |
1099 { | |
440 | 1100 Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj); |
428 | 1101 |
1102 FACE_BOOLEAN_SPECIFIER_FACE (face_boolean) = face; | |
1103 FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean) = property; | |
1104 } | |
1105 | |
1106 DEFUN ("face-boolean-specifier-p", Fface_boolean_specifier_p, 1, 1, 0, /* | |
1107 Return non-nil if OBJECT is a face-boolean specifier. | |
1108 | |
442 | 1109 See `make-face-boolean-specifier' for a description of possible |
1110 face-boolean instantiators. | |
428 | 1111 */ |
1112 (object)) | |
1113 { | |
1114 return FACE_BOOLEAN_SPECIFIERP (object) ? Qt : Qnil; | |
1115 } | |
1116 | |
1117 | |
1118 /************************************************************************/ | |
1119 /* initialization */ | |
1120 /************************************************************************/ | |
1121 | |
1122 void | |
1123 syms_of_objects (void) | |
1124 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1125 INIT_LISP_OBJECT (color_instance); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1126 INIT_LISP_OBJECT (font_instance); |
442 | 1127 |
428 | 1128 DEFSUBR (Fcolor_specifier_p); |
1129 DEFSUBR (Ffont_specifier_p); | |
1130 DEFSUBR (Fface_boolean_specifier_p); | |
1131 | |
563 | 1132 DEFSYMBOL_MULTIWORD_PREDICATE (Qcolor_instancep); |
428 | 1133 DEFSUBR (Fmake_color_instance); |
1134 DEFSUBR (Fcolor_instance_p); | |
1135 DEFSUBR (Fcolor_instance_name); | |
1136 DEFSUBR (Fcolor_instance_rgb_components); | |
1137 DEFSUBR (Fvalid_color_name_p); | |
2527 | 1138 DEFSUBR (Fcolor_list); |
428 | 1139 |
563 | 1140 DEFSYMBOL_MULTIWORD_PREDICATE (Qfont_instancep); |
428 | 1141 DEFSUBR (Fmake_font_instance); |
1142 DEFSUBR (Ffont_instance_p); | |
1143 DEFSUBR (Ffont_instance_name); | |
1144 DEFSUBR (Ffont_instance_ascent); | |
1145 DEFSUBR (Ffont_instance_descent); | |
1146 DEFSUBR (Ffont_instance_width); | |
1147 DEFSUBR (Ffont_instance_proportional_p); | |
1148 DEFSUBR (Ffont_instance_truename); | |
1149 DEFSUBR (Ffont_instance_properties); | |
2527 | 1150 DEFSUBR (Ffont_list); |
428 | 1151 |
1152 /* Qcolor, Qfont defined in general.c */ | |
563 | 1153 DEFSYMBOL (Qface_boolean); |
428 | 1154 } |
1155 | |
1156 void | |
1157 specifier_type_create_objects (void) | |
1158 { | |
1159 INITIALIZE_SPECIFIER_TYPE_WITH_DATA (color, "color", "color-specifier-p"); | |
1160 INITIALIZE_SPECIFIER_TYPE_WITH_DATA (font, "font", "font-specifier-p"); | |
1161 INITIALIZE_SPECIFIER_TYPE_WITH_DATA (face_boolean, "face-boolean", | |
1162 "face-boolean-specifier-p"); | |
1163 | |
1164 SPECIFIER_HAS_METHOD (color, instantiate); | |
1165 SPECIFIER_HAS_METHOD (font, instantiate); | |
1166 SPECIFIER_HAS_METHOD (face_boolean, instantiate); | |
1167 | |
1168 SPECIFIER_HAS_METHOD (color, validate); | |
1169 SPECIFIER_HAS_METHOD (font, validate); | |
1170 SPECIFIER_HAS_METHOD (face_boolean, validate); | |
1171 | |
1172 SPECIFIER_HAS_METHOD (color, create); | |
1173 SPECIFIER_HAS_METHOD (font, create); | |
1174 SPECIFIER_HAS_METHOD (face_boolean, create); | |
1175 | |
1176 SPECIFIER_HAS_METHOD (color, mark); | |
1177 SPECIFIER_HAS_METHOD (font, mark); | |
1178 SPECIFIER_HAS_METHOD (face_boolean, mark); | |
1179 | |
1180 SPECIFIER_HAS_METHOD (color, after_change); | |
1181 SPECIFIER_HAS_METHOD (font, after_change); | |
1182 SPECIFIER_HAS_METHOD (face_boolean, after_change); | |
1183 | |
1184 #ifdef MULE | |
1185 SPECIFIER_HAS_METHOD (font, validate_matchspec); | |
1186 #endif | |
1187 } | |
1188 | |
1189 void | |
1190 reinit_specifier_type_create_objects (void) | |
1191 { | |
1192 REINITIALIZE_SPECIFIER_TYPE (color); | |
1193 REINITIALIZE_SPECIFIER_TYPE (font); | |
1194 REINITIALIZE_SPECIFIER_TYPE (face_boolean); | |
1195 } | |
1196 | |
1197 void | |
1198 reinit_vars_of_objects (void) | |
1199 { | |
1200 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1201 Lisp_Object obj = ALLOC_LISP_OBJECT (color_instance); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1202 Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj); |
428 | 1203 c->name = Qnil; |
1204 c->device = Qnil; | |
1205 c->data = 0; | |
1206 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1207 Vthe_null_color_instance = obj; |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1208 staticpro_nodump (&Vthe_null_color_instance); |
428 | 1209 } |
1210 | |
1211 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1212 Lisp_Object obj = ALLOC_LISP_OBJECT (font_instance); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1213 Lisp_Font_Instance *f = XFONT_INSTANCE (obj); |
428 | 1214 f->name = Qnil; |
872 | 1215 f->truename = Qnil; |
428 | 1216 f->device = Qnil; |
1217 f->data = 0; | |
1218 | |
1219 f->ascent = f->height = 0; | |
1220 f->descent = 0; | |
1221 f->width = 0; | |
1222 f->proportional_p = 0; | |
1223 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1224 Vthe_null_font_instance = obj; |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
1225 staticpro_nodump (&Vthe_null_font_instance); |
428 | 1226 } |
1227 } | |
1228 | |
1229 void | |
1230 vars_of_objects (void) | |
1231 { | |
1232 } |