1 /* Generic glyph/image implementation + display tables
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1995 Tinker Systems
4 Copyright (C) 1995, 1996 Ben Wing
5 Copyright (C) 1995 Sun Microsystems
6 Copyright (C) 1998, 1999 Andy Piper
8 This file is part of XEmacs.
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING. If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* Synched up with: Not in FSF. */
27 /* Written by Ben Wing and Chuck Thompson. */
40 #include "redisplay.h"
45 #include "blocktype.h"
51 Lisp_Object Qimage_conversion_error;
53 Lisp_Object Qglyphp, Qcontrib_p, Qbaseline;
54 Lisp_Object Qbuffer_glyph_p, Qpointer_glyph_p, Qicon_glyph_p;
55 Lisp_Object Qnothing_image_instance_p, Qtext_image_instance_p;
56 Lisp_Object Qmono_pixmap_image_instance_p;
57 Lisp_Object Qcolor_pixmap_image_instance_p;
58 Lisp_Object Qpointer_image_instance_p;
59 Lisp_Object Qsubwindow_image_instance_p;
60 Lisp_Object Qlayout_image_instance_p;
61 Lisp_Object Qwidget_image_instance_p;
62 Lisp_Object Qconst_glyph_variable;
63 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow;
64 Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height;
65 Lisp_Object Qformatted_string;
66 Lisp_Object Vcurrent_display_table;
67 Lisp_Object Vtruncation_glyph, Vcontinuation_glyph, Voctal_escape_glyph;
68 Lisp_Object Vcontrol_arrow_glyph, Vinvisible_text_glyph, Vhscroll_glyph;
69 Lisp_Object Vxemacs_logo;
70 Lisp_Object Vthe_nothing_vector;
71 Lisp_Object Vimage_instantiator_format_list;
72 Lisp_Object Vimage_instance_type_list;
73 Lisp_Object Vglyph_type_list;
75 int disable_animated_pixmaps;
77 DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing);
78 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit);
79 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
80 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
81 DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow);
82 DEFINE_IMAGE_INSTANTIATOR_FORMAT (text);
84 #ifdef HAVE_WINDOW_SYSTEM
85 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm);
88 Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y;
89 Lisp_Object Q_foreground, Q_background;
91 #define BitmapSuccess 0
92 #define BitmapOpenFailed 1
93 #define BitmapFileInvalid 2
94 #define BitmapNoMemory 3
99 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xface);
104 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xpm);
106 Lisp_Object Q_color_symbols;
109 typedef struct image_instantiator_format_entry image_instantiator_format_entry;
110 struct image_instantiator_format_entry
114 struct image_instantiator_methods *meths;
119 Dynarr_declare (struct image_instantiator_format_entry);
120 } image_instantiator_format_entry_dynarr;
122 image_instantiator_format_entry_dynarr *
123 the_image_instantiator_format_entry_dynarr;
125 static Lisp_Object allocate_image_instance (Lisp_Object device);
126 static void image_validate (Lisp_Object instantiator);
127 static void glyph_property_was_changed (Lisp_Object glyph,
128 Lisp_Object property,
130 static void register_ignored_expose (struct frame* f, int x, int y, int width, int height);
131 /* Unfortunately windows and X are different. In windows BeginPaint()
132 will prevent WM_PAINT messages being generated so it is unnecessary
133 to register exposures as they will not occur. Under X they will
135 int hold_ignored_expose_registration;
137 EXFUN (Fimage_instance_type, 1);
138 EXFUN (Fglyph_type, 1);
141 /****************************************************************************
142 * Image Instantiators *
143 ****************************************************************************/
145 struct image_instantiator_methods *
146 decode_device_ii_format (Lisp_Object device, Lisp_Object format,
151 if (!SYMBOLP (format))
153 if (ERRB_EQ (errb, ERROR_ME))
154 CHECK_SYMBOL (format);
158 for (i = 0; i < Dynarr_length (the_image_instantiator_format_entry_dynarr);
162 Dynarr_at (the_image_instantiator_format_entry_dynarr, i).
165 Lisp_Object d = Dynarr_at (the_image_instantiator_format_entry_dynarr, i).
167 if ((NILP (d) && NILP (device))
170 EQ (CONSOLE_TYPE (XCONSOLE
171 (DEVICE_CONSOLE (XDEVICE (device)))), d)))
172 return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths;
176 maybe_signal_simple_error ("Invalid image-instantiator format", format,
182 struct image_instantiator_methods *
183 decode_image_instantiator_format (Lisp_Object format, Error_behavior errb)
185 return decode_device_ii_format (Qnil, format, errb);
189 valid_image_instantiator_format_p (Lisp_Object format, Lisp_Object locale)
192 struct image_instantiator_methods* meths =
193 decode_image_instantiator_format (format, ERROR_ME_NOT);
194 Lisp_Object contype = Qnil;
195 /* mess with the locale */
196 if (!NILP (locale) && SYMBOLP (locale))
200 struct console* console = decode_console (locale);
201 contype = console ? CONSOLE_TYPE (console) : locale;
203 /* nothing is valid in all locales */
204 if (EQ (format, Qnothing))
206 /* reject unknown formats */
207 else if (NILP (contype) || !meths)
210 for (i = 0; i < Dynarr_length (meths->consoles); i++)
211 if (EQ (contype, Dynarr_at (meths->consoles, i).symbol))
216 DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p,
218 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid.
219 If LOCALE is non-nil then the format is checked in that domain.
220 If LOCALE is nil the current console is used.
221 Valid formats are some subset of 'nothing, 'string, 'formatted-string,
222 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font,
223 'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled.
225 (image_instantiator_format, locale))
227 return valid_image_instantiator_format_p (image_instantiator_format, locale) ?
231 DEFUN ("image-instantiator-format-list", Fimage_instantiator_format_list,
233 Return a list of valid image-instantiator formats.
237 return Fcopy_sequence (Vimage_instantiator_format_list);
241 add_entry_to_device_ii_format_list (Lisp_Object device, Lisp_Object symbol,
242 struct image_instantiator_methods *meths)
244 struct image_instantiator_format_entry entry;
246 entry.symbol = symbol;
247 entry.device = device;
249 Dynarr_add (the_image_instantiator_format_entry_dynarr, entry);
250 Vimage_instantiator_format_list =
251 Fcons (symbol, Vimage_instantiator_format_list);
255 add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
257 image_instantiator_methods *meths)
259 add_entry_to_device_ii_format_list (Qnil, symbol, meths);
263 get_image_conversion_list (Lisp_Object console_type)
265 return &decode_console_type (console_type, ERROR_ME)->image_conversion_list;
268 DEFUN ("set-console-type-image-conversion-list", Fset_console_type_image_conversion_list,
270 Set the image-conversion-list for consoles of the given TYPE.
271 The image-conversion-list specifies how image instantiators that
272 are strings should be interpreted. Each element of the list should be
273 a list of two elements (a regular expression string and a vector) or
274 a list of three elements (the preceding two plus an integer index into
275 the vector). The string is converted to the vector associated with the
276 first matching regular expression. If a vector index is specified, the
277 string itself is substituted into that position in the vector.
279 Note: The conversion above is applied when the image instantiator is
280 added to an image specifier, not when the specifier is actually
281 instantiated. Therefore, changing the image-conversion-list only affects
282 newly-added instantiators. Existing instantiators in glyphs and image
283 specifiers will not be affected.
285 (console_type, list))
288 Lisp_Object *imlist = get_image_conversion_list (console_type);
290 /* Check the list to make sure that it only has valid entries. */
292 EXTERNAL_LIST_LOOP (tail, list)
294 Lisp_Object mapping = XCAR (tail);
296 /* Mapping form should be (STRING VECTOR) or (STRING VECTOR INTEGER) */
297 if (!CONSP (mapping) ||
298 !CONSP (XCDR (mapping)) ||
299 (!NILP (XCDR (XCDR (mapping))) &&
300 (!CONSP (XCDR (XCDR (mapping))) ||
301 !NILP (XCDR (XCDR (XCDR (mapping)))))))
302 signal_simple_error ("Invalid mapping form", mapping);
305 Lisp_Object exp = XCAR (mapping);
306 Lisp_Object typevec = XCAR (XCDR (mapping));
307 Lisp_Object pos = Qnil;
312 CHECK_VECTOR (typevec);
313 if (!NILP (XCDR (XCDR (mapping))))
315 pos = XCAR (XCDR (XCDR (mapping)));
317 if (XINT (pos) < 0 ||
318 XINT (pos) >= XVECTOR_LENGTH (typevec))
320 (pos, Qzero, make_int (XVECTOR_LENGTH (typevec) - 1));
323 newvec = Fcopy_sequence (typevec);
325 XVECTOR_DATA (newvec)[XINT (pos)] = exp;
327 image_validate (newvec);
332 *imlist = Fcopy_tree (list, Qt);
336 DEFUN ("console-type-image-conversion-list", Fconsole_type_image_conversion_list,
338 Return the image-conversion-list for devices of the given TYPE.
339 The image-conversion-list specifies how to interpret image string
340 instantiators for the specified console type. See
341 `set-console-type-image-conversion-list' for a description of its syntax.
345 return Fcopy_tree (*get_image_conversion_list (console_type), Qt);
348 /* Process a string instantiator according to the image-conversion-list for
349 CONSOLE_TYPE. Returns a vector. */
352 process_image_string_instantiator (Lisp_Object data,
353 Lisp_Object console_type,
358 LIST_LOOP (tail, *get_image_conversion_list (console_type))
360 Lisp_Object mapping = XCAR (tail);
361 Lisp_Object exp = XCAR (mapping);
362 Lisp_Object typevec = XCAR (XCDR (mapping));
364 /* if the result is of a type that can't be instantiated
365 (e.g. a string when we're dealing with a pointer glyph),
368 IIFORMAT_METH (decode_image_instantiator_format
369 (XVECTOR_DATA (typevec)[0], ERROR_ME),
370 possible_dest_types, ())))
372 if (fast_string_match (exp, 0, data, 0, -1, 0, ERROR_ME, 0) >= 0)
374 if (!NILP (XCDR (XCDR (mapping))))
376 int pos = XINT (XCAR (XCDR (XCDR (mapping))));
377 Lisp_Object newvec = Fcopy_sequence (typevec);
378 XVECTOR_DATA (newvec)[pos] = data;
387 signal_simple_error ("Unable to interpret glyph instantiator",
394 find_keyword_in_vector_or_given (Lisp_Object vector, Lisp_Object keyword,
395 Lisp_Object default_)
398 int instantiator_len;
400 elt = XVECTOR_DATA (vector);
401 instantiator_len = XVECTOR_LENGTH (vector);
406 while (instantiator_len > 0)
408 if (EQ (elt[0], keyword))
411 instantiator_len -= 2;
418 find_keyword_in_vector (Lisp_Object vector, Lisp_Object keyword)
420 return find_keyword_in_vector_or_given (vector, keyword, Qnil);
424 check_valid_string (Lisp_Object data)
430 check_valid_vector (Lisp_Object data)
436 check_valid_face (Lisp_Object data)
442 check_valid_int (Lisp_Object data)
448 file_or_data_must_be_present (Lisp_Object instantiator)
450 if (NILP (find_keyword_in_vector (instantiator, Q_file)) &&
451 NILP (find_keyword_in_vector (instantiator, Q_data)))
452 signal_simple_error ("Must supply either :file or :data",
457 data_must_be_present (Lisp_Object instantiator)
459 if (NILP (find_keyword_in_vector (instantiator, Q_data)))
460 signal_simple_error ("Must supply :data", instantiator);
464 face_must_be_present (Lisp_Object instantiator)
466 if (NILP (find_keyword_in_vector (instantiator, Q_face)))
467 signal_simple_error ("Must supply :face", instantiator);
470 /* utility function useful in retrieving data from a file. */
473 make_string_from_file (Lisp_Object file)
475 /* This function can call lisp */
476 int count = specpdl_depth ();
477 Lisp_Object temp_buffer;
481 specbind (Qinhibit_quit, Qt);
482 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
483 temp_buffer = Fget_buffer_create (build_string (" *pixmap conversion*"));
484 GCPRO1 (temp_buffer);
485 set_buffer_internal (XBUFFER (temp_buffer));
486 Ferase_buffer (Qnil);
487 specbind (intern ("format-alist"), Qnil);
488 Finsert_file_contents_internal (file, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil);
489 data = Fbuffer_substring (Qnil, Qnil, Qnil);
490 unbind_to (count, Qnil);
495 /* The following two functions are provided to make it easier for
496 the normalize methods to work with keyword-value vectors.
497 Hash tables are kind of heavyweight for this purpose.
498 (If vectors were resizable, we could avoid this problem;
499 but they're not.) An alternative approach that might be
500 more efficient but require more work is to use a type of
501 assoc-Dynarr and provide primitives for deleting elements out
502 of it. (However, you'd also have to add an unwind-protect
503 to make sure the Dynarr got freed in case of an error in
504 the normalization process.) */
507 tagged_vector_to_alist (Lisp_Object vector)
509 Lisp_Object *elt = XVECTOR_DATA (vector);
510 int len = XVECTOR_LENGTH (vector);
511 Lisp_Object result = Qnil;
514 for (len -= 2; len >= 1; len -= 2)
515 result = Fcons (Fcons (elt[len], elt[len+1]), result);
521 alist_to_tagged_vector (Lisp_Object tag, Lisp_Object alist)
523 int len = 1 + 2 * XINT (Flength (alist));
524 Lisp_Object *elt = alloca_array (Lisp_Object, len);
530 LIST_LOOP (rest, alist)
532 Lisp_Object pair = XCAR (rest);
533 elt[i] = XCAR (pair);
534 elt[i+1] = XCDR (pair);
538 return Fvector (len, elt);
542 normalize_image_instantiator (Lisp_Object instantiator,
544 Lisp_Object dest_mask)
546 if (IMAGE_INSTANCEP (instantiator))
549 if (STRINGP (instantiator))
550 instantiator = process_image_string_instantiator (instantiator, contype,
553 assert (VECTORP (instantiator));
554 /* We have to always store the actual pixmap data and not the
555 filename even though this is a potential memory pig. We have to
556 do this because it is quite possible that we will need to
557 instantiate a new instance of the pixmap and the file will no
558 longer exist (e.g. w3 pixmaps are almost always from temporary
562 struct image_instantiator_methods *meths;
564 GCPRO1 (instantiator);
566 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
568 RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize,
569 (instantiator, contype),
575 instantiate_image_instantiator (Lisp_Object device, Lisp_Object domain,
576 Lisp_Object instantiator,
577 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
580 Lisp_Object ii = allocate_image_instance (device);
581 struct image_instantiator_methods *meths;
586 if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0], device))
588 ("Image instantiator format is invalid in this locale.",
591 meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
593 methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate);
594 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
595 pointer_bg, dest_mask, domain));
597 /* now do device specific instantiation */
598 meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0],
601 if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate)))
603 ("Don't know how to instantiate this image instantiator?",
605 MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
606 pointer_bg, dest_mask, domain));
613 /****************************************************************************
614 * Image-Instance Object *
615 ****************************************************************************/
617 Lisp_Object Qimage_instancep;
620 mark_image_instance (Lisp_Object obj)
622 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
624 mark_object (i->name);
625 switch (IMAGE_INSTANCE_TYPE (i))
628 mark_object (IMAGE_INSTANCE_TEXT_STRING (i));
630 case IMAGE_MONO_PIXMAP:
631 case IMAGE_COLOR_PIXMAP:
632 mark_object (IMAGE_INSTANCE_PIXMAP_FILENAME (i));
633 mark_object (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i));
634 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i));
635 mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i));
636 mark_object (IMAGE_INSTANCE_PIXMAP_FG (i));
637 mark_object (IMAGE_INSTANCE_PIXMAP_BG (i));
641 mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i));
642 mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i));
643 mark_object (IMAGE_INSTANCE_WIDGET_FACE (i));
644 mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i));
645 case IMAGE_SUBWINDOW:
646 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
650 mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i));
651 mark_object (IMAGE_INSTANCE_LAYOUT_BORDER (i));
652 mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
659 MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i));
665 print_image_instance (Lisp_Object obj, Lisp_Object printcharfun,
669 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (obj);
672 error ("printing unreadable object #<image-instance 0x%x>",
674 write_c_string ("#<image-instance (", printcharfun);
675 print_internal (Fimage_instance_type (obj), printcharfun, 0);
676 write_c_string (") ", printcharfun);
677 if (!NILP (ii->name))
679 print_internal (ii->name, printcharfun, 1);
680 write_c_string (" ", printcharfun);
682 write_c_string ("on ", printcharfun);
683 print_internal (ii->device, printcharfun, 0);
684 write_c_string (" ", printcharfun);
685 switch (IMAGE_INSTANCE_TYPE (ii))
691 print_internal (IMAGE_INSTANCE_TEXT_STRING (ii), printcharfun, 1);
694 case IMAGE_MONO_PIXMAP:
695 case IMAGE_COLOR_PIXMAP:
697 if (STRINGP (IMAGE_INSTANCE_PIXMAP_FILENAME (ii)))
700 Lisp_Object filename = IMAGE_INSTANCE_PIXMAP_FILENAME (ii);
701 s = strrchr ((char *) XSTRING_DATA (filename), '/');
703 print_internal (build_string (s + 1), printcharfun, 1);
705 print_internal (filename, printcharfun, 1);
707 if (IMAGE_INSTANCE_PIXMAP_DEPTH (ii) > 1)
708 sprintf (buf, " %dx%dx%d", IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
709 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii),
710 IMAGE_INSTANCE_PIXMAP_DEPTH (ii));
712 sprintf (buf, " %dx%d", IMAGE_INSTANCE_PIXMAP_WIDTH (ii),
713 IMAGE_INSTANCE_PIXMAP_HEIGHT (ii));
714 write_c_string (buf, printcharfun);
715 if (!NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)) ||
716 !NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)))
718 write_c_string (" @", printcharfun);
719 if (!NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)))
721 long_to_string (buf, XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (ii)));
722 write_c_string (buf, printcharfun);
725 write_c_string ("??", printcharfun);
726 write_c_string (",", printcharfun);
727 if (!NILP (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)))
729 long_to_string (buf, XINT (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii)));
730 write_c_string (buf, printcharfun);
733 write_c_string ("??", printcharfun);
735 if (!NILP (IMAGE_INSTANCE_PIXMAP_FG (ii)) ||
736 !NILP (IMAGE_INSTANCE_PIXMAP_BG (ii)))
738 write_c_string (" (", printcharfun);
739 if (!NILP (IMAGE_INSTANCE_PIXMAP_FG (ii)))
743 (IMAGE_INSTANCE_PIXMAP_FG (ii))->name, printcharfun, 0);
745 write_c_string ("/", printcharfun);
746 if (!NILP (IMAGE_INSTANCE_PIXMAP_BG (ii)))
750 (IMAGE_INSTANCE_PIXMAP_BG (ii))->name, printcharfun, 0);
752 write_c_string (")", printcharfun);
758 if (!NILP (IMAGE_INSTANCE_WIDGET_CALLBACK (ii)))
760 print_internal (IMAGE_INSTANCE_WIDGET_CALLBACK (ii), printcharfun, 0);
761 write_c_string (", ", printcharfun);
764 if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii)))
766 write_c_string (" (", printcharfun);
768 (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
769 write_c_string (")", printcharfun);
772 if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
773 print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
775 case IMAGE_SUBWINDOW:
777 sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii),
778 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii));
779 write_c_string (buf, printcharfun);
781 /* This is stolen from frame.c. Subwindows are strange in that they
782 are specific to a particular frame so we want to print in their
783 description what that frame is. */
785 write_c_string (" on #<", printcharfun);
787 struct frame* f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
789 if (!FRAME_LIVE_P (f))
790 write_c_string ("dead", printcharfun);
792 write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))),
795 write_c_string ("-frame ", printcharfun);
797 write_c_string (">", printcharfun);
798 sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
799 write_c_string (buf, printcharfun);
807 MAYBE_DEVMETH (XDEVICE (ii->device), print_image_instance,
808 (ii, printcharfun, escapeflag));
809 sprintf (buf, " 0x%x>", ii->header.uid);
810 write_c_string (buf, printcharfun);
814 finalize_image_instance (void *header, int for_disksave)
816 struct Lisp_Image_Instance *i = (struct Lisp_Image_Instance *) header;
818 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING)
819 /* objects like this exist at dump time, so don't bomb out. */
821 if (for_disksave) finalose (i);
823 /* do this so that the cachels get reset */
824 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET
826 IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW)
828 MARK_FRAME_SUBWINDOWS_CHANGED
829 (XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)));
832 MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i));
836 image_instance_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
838 struct Lisp_Image_Instance *i1 = XIMAGE_INSTANCE (obj1);
839 struct Lisp_Image_Instance *i2 = XIMAGE_INSTANCE (obj2);
840 struct device *d1 = XDEVICE (i1->device);
841 struct device *d2 = XDEVICE (i2->device);
845 if (IMAGE_INSTANCE_TYPE (i1) != IMAGE_INSTANCE_TYPE (i2))
847 if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2),
851 switch (IMAGE_INSTANCE_TYPE (i1))
857 if (!internal_equal (IMAGE_INSTANCE_TEXT_STRING (i1),
858 IMAGE_INSTANCE_TEXT_STRING (i2),
863 case IMAGE_MONO_PIXMAP:
864 case IMAGE_COLOR_PIXMAP:
866 if (!(IMAGE_INSTANCE_PIXMAP_WIDTH (i1) ==
867 IMAGE_INSTANCE_PIXMAP_WIDTH (i2) &&
868 IMAGE_INSTANCE_PIXMAP_HEIGHT (i1) ==
869 IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) &&
870 IMAGE_INSTANCE_PIXMAP_DEPTH (i1) ==
871 IMAGE_INSTANCE_PIXMAP_DEPTH (i2) &&
872 IMAGE_INSTANCE_PIXMAP_SLICE (i1) ==
873 IMAGE_INSTANCE_PIXMAP_SLICE (i2) &&
874 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1),
875 IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) &&
876 EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1),
877 IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i2)) &&
878 internal_equal (IMAGE_INSTANCE_PIXMAP_FILENAME (i1),
879 IMAGE_INSTANCE_PIXMAP_FILENAME (i2),
881 internal_equal (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i1),
882 IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i2),
888 if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1),
889 IMAGE_INSTANCE_WIDGET_TYPE (i2))
890 && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1),
891 IMAGE_INSTANCE_WIDGET_ITEMS (i2),
893 && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1),
894 IMAGE_INSTANCE_WIDGET_PROPS (i2),
899 if (IMAGE_INSTANCE_TYPE (i1) == IMAGE_LAYOUT
901 !(EQ (IMAGE_INSTANCE_LAYOUT_BORDER (i1),
902 IMAGE_INSTANCE_LAYOUT_BORDER (i2))
904 internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1),
905 IMAGE_INSTANCE_LAYOUT_CHILDREN (i2),
908 case IMAGE_SUBWINDOW:
909 if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) ==
910 IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) &&
911 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) ==
912 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i2) &&
913 IMAGE_INSTANCE_SUBWINDOW_ID (i1) ==
914 IMAGE_INSTANCE_SUBWINDOW_ID (i2)))
922 return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1);
926 image_instance_hash (Lisp_Object obj, int depth)
928 struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
929 struct device *d = XDEVICE (i->device);
930 unsigned long hash = (unsigned long) d;
932 switch (IMAGE_INSTANCE_TYPE (i))
938 hash = HASH2 (hash, internal_hash (IMAGE_INSTANCE_TEXT_STRING (i),
942 case IMAGE_MONO_PIXMAP:
943 case IMAGE_COLOR_PIXMAP:
945 hash = HASH6 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i),
946 IMAGE_INSTANCE_PIXMAP_HEIGHT (i),
947 IMAGE_INSTANCE_PIXMAP_DEPTH (i),
948 IMAGE_INSTANCE_PIXMAP_SLICE (i),
949 internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i),
955 internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1),
956 internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
957 internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1));
959 if (IMAGE_INSTANCE_TYPE (i) == IMAGE_LAYOUT)
961 internal_hash (IMAGE_INSTANCE_LAYOUT_BORDER (i), depth + 1),
962 internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i),
964 case IMAGE_SUBWINDOW:
965 hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i),
966 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i),
967 (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
974 return HASH2 (hash, DEVMETH_OR_GIVEN (d, image_instance_hash, (i, depth),
978 DEFINE_LRECORD_IMPLEMENTATION ("image-instance", image_instance,
979 mark_image_instance, print_image_instance,
980 finalize_image_instance, image_instance_equal,
981 image_instance_hash, 0,
982 struct Lisp_Image_Instance);
985 allocate_image_instance (Lisp_Object device)
987 struct Lisp_Image_Instance *lp =
988 alloc_lcrecord_type (struct Lisp_Image_Instance, &lrecord_image_instance);
993 lp->type = IMAGE_NOTHING;
997 XSETIMAGE_INSTANCE (val, lp);
1001 static enum image_instance_type
1002 decode_image_instance_type (Lisp_Object type, Error_behavior errb)
1004 if (ERRB_EQ (errb, ERROR_ME))
1005 CHECK_SYMBOL (type);
1007 if (EQ (type, Qnothing)) return IMAGE_NOTHING;
1008 if (EQ (type, Qtext)) return IMAGE_TEXT;
1009 if (EQ (type, Qmono_pixmap)) return IMAGE_MONO_PIXMAP;
1010 if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP;
1011 if (EQ (type, Qpointer)) return IMAGE_POINTER;
1012 if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW;
1013 if (EQ (type, Qwidget)) return IMAGE_WIDGET;
1014 if (EQ (type, Qlayout)) return IMAGE_LAYOUT;
1016 maybe_signal_simple_error ("Invalid image-instance type", type,
1019 return IMAGE_UNKNOWN; /* not reached */
1023 encode_image_instance_type (enum image_instance_type type)
1027 case IMAGE_NOTHING: return Qnothing;
1028 case IMAGE_TEXT: return Qtext;
1029 case IMAGE_MONO_PIXMAP: return Qmono_pixmap;
1030 case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap;
1031 case IMAGE_POINTER: return Qpointer;
1032 case IMAGE_SUBWINDOW: return Qsubwindow;
1033 case IMAGE_WIDGET: return Qwidget;
1034 case IMAGE_LAYOUT: return Qlayout;
1039 return Qnil; /* not reached */
1043 image_instance_type_to_mask (enum image_instance_type type)
1045 /* This depends on the fact that enums are assigned consecutive
1046 integers starting at 0. (Remember that IMAGE_UNKNOWN is the
1047 first enum.) I'm fairly sure this behavior is ANSI-mandated,
1048 so there should be no portability problems here. */
1049 return (1 << ((int) (type) - 1));
1053 decode_image_instance_type_list (Lisp_Object list)
1063 enum image_instance_type type =
1064 decode_image_instance_type (list, ERROR_ME);
1065 return image_instance_type_to_mask (type);
1068 EXTERNAL_LIST_LOOP (rest, list)
1070 enum image_instance_type type =
1071 decode_image_instance_type (XCAR (rest), ERROR_ME);
1072 mask |= image_instance_type_to_mask (type);
1079 encode_image_instance_type_list (int mask)
1082 Lisp_Object result = Qnil;
1088 result = Fcons (encode_image_instance_type
1089 ((enum image_instance_type) count), result);
1093 return Fnreverse (result);
1097 incompatible_image_types (Lisp_Object instantiator, int given_dest_mask,
1098 int desired_dest_mask)
1103 (emacs_doprnt_string_lisp_2
1105 "No compatible image-instance types given: wanted one of %s, got %s",
1107 encode_image_instance_type_list (desired_dest_mask),
1108 encode_image_instance_type_list (given_dest_mask)),
1113 valid_image_instance_type_p (Lisp_Object type)
1115 return !NILP (memq_no_quit (type, Vimage_instance_type_list));
1118 DEFUN ("valid-image-instance-type-p", Fvalid_image_instance_type_p, 1, 1, 0, /*
1119 Given an IMAGE-INSTANCE-TYPE, return non-nil if it is valid.
1120 Valid types are some subset of 'nothing, 'text, 'mono-pixmap, 'color-pixmap,
1121 'pointer, and 'subwindow, depending on how XEmacs was compiled.
1123 (image_instance_type))
1125 return valid_image_instance_type_p (image_instance_type) ? Qt : Qnil;
1128 DEFUN ("image-instance-type-list", Fimage_instance_type_list, 0, 0, 0, /*
1129 Return a list of valid image-instance types.
1133 return Fcopy_sequence (Vimage_instance_type_list);
1137 decode_error_behavior_flag (Lisp_Object no_error)
1139 if (NILP (no_error)) return ERROR_ME;
1140 else if (EQ (no_error, Qt)) return ERROR_ME_NOT;
1141 else return ERROR_ME_WARN;
1145 encode_error_behavior_flag (Error_behavior errb)
1147 if (ERRB_EQ (errb, ERROR_ME))
1149 else if (ERRB_EQ (errb, ERROR_ME_NOT))
1153 assert (ERRB_EQ (errb, ERROR_ME_WARN));
1159 make_image_instance_1 (Lisp_Object data, Lisp_Object device,
1160 Lisp_Object dest_types)
1163 struct gcpro gcpro1;
1166 XSETDEVICE (device, decode_device (device));
1167 /* instantiate_image_instantiator() will abort if given an
1168 image instance ... */
1169 if (IMAGE_INSTANCEP (data))
1170 signal_simple_error ("Image instances not allowed here", data);
1171 image_validate (data);
1172 dest_mask = decode_image_instance_type_list (dest_types);
1173 data = normalize_image_instantiator (data, DEVICE_TYPE (XDEVICE (device)),
1174 make_int (dest_mask));
1176 if (VECTORP (data) && EQ (XVECTOR_DATA (data)[0], Qinherit))
1177 signal_simple_error ("Inheritance not allowed here", data);
1178 ii = instantiate_image_instantiator (device, device, data,
1179 Qnil, Qnil, dest_mask);
1180 RETURN_UNGCPRO (ii);
1183 DEFUN ("make-image-instance", Fmake_image_instance, 1, 4, 0, /*
1184 Return a new `image-instance' object.
1186 Image-instance objects encapsulate the way a particular image (pixmap,
1187 etc.) is displayed on a particular device. In most circumstances, you
1188 do not need to directly create image instances; use a glyph instead.
1189 However, it may occasionally be useful to explicitly create image
1190 instances, if you want more control over the instantiation process.
1192 DATA is an image instantiator, which describes the image; see
1193 `image-specifier-p' for a description of the allowed values.
1195 DEST-TYPES should be a list of allowed image instance types that can
1196 be generated. The recognized image instance types are
1199 Nothing is displayed.
1201 Displayed as text. The foreground and background colors and the
1202 font of the text are specified independent of the pixmap. Typically
1203 these attributes will come from the face of the surrounding text,
1204 unless a face is specified for the glyph in which the image appears.
1206 Displayed as a mono pixmap (a pixmap with only two colors where the
1207 foreground and background can be specified independent of the pixmap;
1208 typically the pixmap assumes the foreground and background colors of
1209 the text around it, unless a face is specified for the glyph in which
1212 Displayed as a color pixmap.
1214 Used as the mouse pointer for a window.
1216 A child window that is treated as an image. This allows (e.g.)
1217 another program to be responsible for drawing into the window.
1219 A child window that contains a window-system widget, e.g. a push
1222 The DEST-TYPES list is unordered. If multiple destination types
1223 are possible for a given instantiator, the "most natural" type
1224 for the instantiator's format is chosen. (For XBM, the most natural
1225 types are `mono-pixmap', followed by `color-pixmap', followed by
1226 `pointer'. For the other normal image formats, the most natural
1227 types are `color-pixmap', followed by `mono-pixmap', followed by
1228 `pointer'. For the string and formatted-string formats, the most
1229 natural types are `text', followed by `mono-pixmap' (not currently
1230 implemented), followed by `color-pixmap' (not currently implemented).
1231 The other formats can only be instantiated as one type. (If you
1232 want to control more specifically the order of the types into which
1233 an image is instantiated, just call `make-image-instance' repeatedly
1234 until it succeeds, passing less and less preferred destination types
1237 If DEST-TYPES is omitted, all possible types are allowed.
1239 NO-ERROR controls what happens when the image cannot be generated.
1240 If nil, an error message is generated. If t, no messages are
1241 generated and this function returns nil. If anything else, a warning
1242 message is generated and this function returns nil.
1244 (data, device, dest_types, no_error))
1246 Error_behavior errb = decode_error_behavior_flag (no_error);
1248 return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1,
1250 3, data, device, dest_types);
1253 DEFUN ("image-instance-p", Fimage_instance_p, 1, 1, 0, /*
1254 Return non-nil if OBJECT is an image instance.
1258 return IMAGE_INSTANCEP (object) ? Qt : Qnil;
1261 DEFUN ("image-instance-type", Fimage_instance_type, 1, 1, 0, /*
1262 Return the type of the given image instance.
1263 The return value will be one of 'nothing, 'text, 'mono-pixmap,
1264 'color-pixmap, 'pointer, or 'subwindow.
1268 CHECK_IMAGE_INSTANCE (image_instance);
1269 return encode_image_instance_type (XIMAGE_INSTANCE_TYPE (image_instance));
1272 DEFUN ("image-instance-name", Fimage_instance_name, 1, 1, 0, /*
1273 Return the name of the given image instance.
1277 CHECK_IMAGE_INSTANCE (image_instance);
1278 return XIMAGE_INSTANCE_NAME (image_instance);
1281 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /*
1282 Return the string of the given image instance.
1283 This will only be non-nil for text image instances and widgets.
1287 CHECK_IMAGE_INSTANCE (image_instance);
1288 if (XIMAGE_INSTANCE_TYPE (image_instance) == IMAGE_TEXT)
1289 return XIMAGE_INSTANCE_TEXT_STRING (image_instance);
1290 else if (XIMAGE_INSTANCE_TYPE (image_instance) == IMAGE_WIDGET)
1291 return XIMAGE_INSTANCE_WIDGET_TEXT (image_instance);
1296 DEFUN ("image-instance-property", Fimage_instance_property, 2, 2, 0, /*
1297 Return the given property of the given image instance.
1298 Returns nil if the property or the property method do not exist for
1299 the image instance in the domain.
1301 (image_instance, prop))
1303 struct Lisp_Image_Instance* ii;
1304 Lisp_Object type, ret;
1305 struct image_instantiator_methods* meths;
1307 CHECK_IMAGE_INSTANCE (image_instance);
1308 CHECK_SYMBOL (prop);
1309 ii = XIMAGE_INSTANCE (image_instance);
1311 /* ... then try device specific methods ... */
1312 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1313 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
1314 type, ERROR_ME_NOT);
1315 if (meths && HAS_IIFORMAT_METH_P (meths, property)
1317 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop))))
1321 /* ... then format specific methods ... */
1322 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1323 if (meths && HAS_IIFORMAT_METH_P (meths, property)
1325 !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop))))
1333 DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /*
1334 Set the given property of the given image instance.
1335 Does nothing if the property or the property method do not exist for
1336 the image instance in the domain.
1338 (image_instance, prop, val))
1340 struct Lisp_Image_Instance* ii;
1341 Lisp_Object type, ret;
1342 struct image_instantiator_methods* meths;
1344 CHECK_IMAGE_INSTANCE (image_instance);
1345 CHECK_SYMBOL (prop);
1346 ii = XIMAGE_INSTANCE (image_instance);
1347 type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
1348 /* try device specific methods first ... */
1349 meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii),
1350 type, ERROR_ME_NOT);
1351 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
1354 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
1360 /* ... then format specific methods ... */
1361 meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
1362 if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
1365 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
1375 /* Make sure the image instance gets redisplayed. */
1376 MARK_IMAGE_INSTANCE_CHANGED (ii);
1377 MARK_SUBWINDOWS_STATE_CHANGED;
1378 MARK_GLYPHS_CHANGED;
1383 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /*
1384 Return the file name from which IMAGE-INSTANCE was read, if known.
1388 CHECK_IMAGE_INSTANCE (image_instance);
1390 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1392 case IMAGE_MONO_PIXMAP:
1393 case IMAGE_COLOR_PIXMAP:
1395 return XIMAGE_INSTANCE_PIXMAP_FILENAME (image_instance);
1402 DEFUN ("image-instance-mask-file-name", Fimage_instance_mask_file_name, 1, 1, 0, /*
1403 Return the file name from which IMAGE-INSTANCE's mask was read, if known.
1407 CHECK_IMAGE_INSTANCE (image_instance);
1409 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1411 case IMAGE_MONO_PIXMAP:
1412 case IMAGE_COLOR_PIXMAP:
1414 return XIMAGE_INSTANCE_PIXMAP_MASK_FILENAME (image_instance);
1421 DEFUN ("image-instance-depth", Fimage_instance_depth, 1, 1, 0, /*
1422 Return the depth of the image instance.
1423 This is 0 for a bitmap, or a positive integer for a pixmap.
1427 CHECK_IMAGE_INSTANCE (image_instance);
1429 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1431 case IMAGE_MONO_PIXMAP:
1432 case IMAGE_COLOR_PIXMAP:
1434 return make_int (XIMAGE_INSTANCE_PIXMAP_DEPTH (image_instance));
1441 DEFUN ("image-instance-height", Fimage_instance_height, 1, 1, 0, /*
1442 Return the height of the image instance, in pixels.
1446 CHECK_IMAGE_INSTANCE (image_instance);
1448 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1450 case IMAGE_MONO_PIXMAP:
1451 case IMAGE_COLOR_PIXMAP:
1453 return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance));
1455 case IMAGE_SUBWINDOW:
1458 return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance));
1465 DEFUN ("image-instance-width", Fimage_instance_width, 1, 1, 0, /*
1466 Return the width of the image instance, in pixels.
1470 CHECK_IMAGE_INSTANCE (image_instance);
1472 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1474 case IMAGE_MONO_PIXMAP:
1475 case IMAGE_COLOR_PIXMAP:
1477 return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance));
1479 case IMAGE_SUBWINDOW:
1482 return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance));
1489 DEFUN ("image-instance-hotspot-x", Fimage_instance_hotspot_x, 1, 1, 0, /*
1490 Return the X coordinate of the image instance's hotspot, if known.
1491 This is a point relative to the origin of the pixmap. When an image is
1492 used as a mouse pointer, the hotspot is the point on the image that sits
1493 over the location that the pointer points to. This is, for example, the
1494 tip of the arrow or the center of the crosshairs.
1495 This will always be nil for a non-pointer image instance.
1499 CHECK_IMAGE_INSTANCE (image_instance);
1501 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1503 case IMAGE_MONO_PIXMAP:
1504 case IMAGE_COLOR_PIXMAP:
1506 return XIMAGE_INSTANCE_PIXMAP_HOTSPOT_X (image_instance);
1513 DEFUN ("image-instance-hotspot-y", Fimage_instance_hotspot_y, 1, 1, 0, /*
1514 Return the Y coordinate of the image instance's hotspot, if known.
1515 This is a point relative to the origin of the pixmap. When an image is
1516 used as a mouse pointer, the hotspot is the point on the image that sits
1517 over the location that the pointer points to. This is, for example, the
1518 tip of the arrow or the center of the crosshairs.
1519 This will always be nil for a non-pointer image instance.
1523 CHECK_IMAGE_INSTANCE (image_instance);
1525 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1527 case IMAGE_MONO_PIXMAP:
1528 case IMAGE_COLOR_PIXMAP:
1530 return XIMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (image_instance);
1537 DEFUN ("image-instance-foreground", Fimage_instance_foreground, 1, 1, 0, /*
1538 Return the foreground color of IMAGE-INSTANCE, if applicable.
1539 This will be a color instance or nil. (It will only be non-nil for
1540 colorized mono pixmaps and for pointers.)
1544 CHECK_IMAGE_INSTANCE (image_instance);
1546 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1548 case IMAGE_MONO_PIXMAP:
1549 case IMAGE_COLOR_PIXMAP:
1551 return XIMAGE_INSTANCE_PIXMAP_FG (image_instance);
1554 return FACE_FOREGROUND (
1555 XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
1556 XIMAGE_INSTANCE_SUBWINDOW_FRAME
1564 DEFUN ("image-instance-background", Fimage_instance_background, 1, 1, 0, /*
1565 Return the background color of IMAGE-INSTANCE, if applicable.
1566 This will be a color instance or nil. (It will only be non-nil for
1567 colorized mono pixmaps and for pointers.)
1571 CHECK_IMAGE_INSTANCE (image_instance);
1573 switch (XIMAGE_INSTANCE_TYPE (image_instance))
1575 case IMAGE_MONO_PIXMAP:
1576 case IMAGE_COLOR_PIXMAP:
1578 return XIMAGE_INSTANCE_PIXMAP_BG (image_instance);
1581 return FACE_BACKGROUND (
1582 XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
1583 XIMAGE_INSTANCE_SUBWINDOW_FRAME
1592 DEFUN ("colorize-image-instance", Fcolorize_image_instance, 3, 3, 0, /*
1593 Make the image instance be displayed in the given colors.
1594 This function returns a new image instance that is exactly like the
1595 specified one except that (if possible) the foreground and background
1596 colors and as specified. Currently, this only does anything if the image
1597 instance is a mono pixmap; otherwise, the same image instance is returned.
1599 (image_instance, foreground, background))
1604 CHECK_IMAGE_INSTANCE (image_instance);
1605 CHECK_COLOR_INSTANCE (foreground);
1606 CHECK_COLOR_INSTANCE (background);
1608 device = XIMAGE_INSTANCE_DEVICE (image_instance);
1609 if (!HAS_DEVMETH_P (XDEVICE (device), colorize_image_instance))
1610 return image_instance;
1612 new = allocate_image_instance (device);
1613 copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance));
1614 /* note that if this method returns non-zero, this method MUST
1615 copy any window-system resources, so that when one image instance is
1616 freed, the other one is not hosed. */
1617 if (!DEVMETH (XDEVICE (device), colorize_image_instance, (new, foreground,
1619 return image_instance;
1624 /************************************************************************/
1626 /************************************************************************/
1628 signal_image_error (CONST char *reason, Lisp_Object frob)
1630 signal_error (Qimage_conversion_error,
1631 list2 (build_translated_string (reason), frob));
1635 signal_image_error_2 (CONST char *reason, Lisp_Object frob0, Lisp_Object frob1)
1637 signal_error (Qimage_conversion_error,
1638 list3 (build_translated_string (reason), frob0, frob1));
1641 /****************************************************************************
1643 ****************************************************************************/
1646 nothing_possible_dest_types (void)
1648 return IMAGE_NOTHING_MASK;
1652 nothing_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1653 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1654 int dest_mask, Lisp_Object domain)
1656 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1658 if (dest_mask & IMAGE_NOTHING_MASK)
1659 IMAGE_INSTANCE_TYPE (ii) = IMAGE_NOTHING;
1661 incompatible_image_types (instantiator, dest_mask, IMAGE_NOTHING_MASK);
1665 /****************************************************************************
1667 ****************************************************************************/
1670 inherit_validate (Lisp_Object instantiator)
1672 face_must_be_present (instantiator);
1676 inherit_normalize (Lisp_Object inst, Lisp_Object console_type)
1680 assert (XVECTOR_LENGTH (inst) == 3);
1681 face = XVECTOR_DATA (inst)[2];
1683 inst = vector3 (Qinherit, Q_face, Fget_face (face));
1688 inherit_possible_dest_types (void)
1690 return IMAGE_MONO_PIXMAP_MASK;
1694 inherit_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1695 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1696 int dest_mask, Lisp_Object domain)
1698 /* handled specially in image_instantiate */
1703 /****************************************************************************
1705 ****************************************************************************/
1708 string_validate (Lisp_Object instantiator)
1710 data_must_be_present (instantiator);
1714 string_possible_dest_types (void)
1716 return IMAGE_TEXT_MASK;
1719 /* called from autodetect_instantiate() */
1721 string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1722 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1723 int dest_mask, Lisp_Object domain)
1725 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1726 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1728 assert (!NILP (data));
1729 if (dest_mask & IMAGE_TEXT_MASK)
1731 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT;
1732 IMAGE_INSTANCE_TEXT_STRING (ii) = data;
1735 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK);
1738 /* set the properties of a string */
1740 text_set_property (Lisp_Object image_instance, Lisp_Object prop,
1743 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1745 if (EQ (prop, Q_data))
1748 IMAGE_INSTANCE_TEXT_STRING (ii) = val;
1756 /****************************************************************************
1757 * formatted-string *
1758 ****************************************************************************/
1761 formatted_string_validate (Lisp_Object instantiator)
1763 data_must_be_present (instantiator);
1767 formatted_string_possible_dest_types (void)
1769 return IMAGE_TEXT_MASK;
1773 formatted_string_instantiate (Lisp_Object image_instance,
1774 Lisp_Object instantiator,
1775 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1776 int dest_mask, Lisp_Object domain)
1778 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
1779 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
1781 assert (!NILP (data));
1782 /* #### implement this */
1783 warn_when_safe (Qunimplemented, Qnotice,
1784 "`formatted-string' not yet implemented; assuming `string'");
1785 if (dest_mask & IMAGE_TEXT_MASK)
1787 IMAGE_INSTANCE_TYPE (ii) = IMAGE_TEXT;
1788 IMAGE_INSTANCE_TEXT_STRING (ii) = data;
1791 incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK);
1795 /************************************************************************/
1796 /* pixmap file functions */
1797 /************************************************************************/
1799 /* If INSTANTIATOR refers to inline data, return Qnil.
1800 If INSTANTIATOR refers to data in a file, return the full filename
1801 if it exists; otherwise, return a cons of (filename).
1803 FILE_KEYWORD and DATA_KEYWORD are symbols specifying the
1804 keywords used to look up the file and inline data,
1805 respectively, in the instantiator. Normally these would
1806 be Q_file and Q_data, but might be different for mask data. */
1809 potential_pixmap_file_instantiator (Lisp_Object instantiator,
1810 Lisp_Object file_keyword,
1811 Lisp_Object data_keyword,
1812 Lisp_Object console_type)
1817 assert (VECTORP (instantiator));
1819 data = find_keyword_in_vector (instantiator, data_keyword);
1820 file = find_keyword_in_vector (instantiator, file_keyword);
1822 if (!NILP (file) && NILP (data))
1824 Lisp_Object retval = MAYBE_LISP_CONTYPE_METH
1825 (decode_console_type(console_type, ERROR_ME),
1826 locate_pixmap_file, (file));
1831 return Fcons (file, Qnil); /* should have been file */
1838 simple_image_type_normalize (Lisp_Object inst, Lisp_Object console_type,
1839 Lisp_Object image_type_tag)
1841 /* This function can call lisp */
1842 Lisp_Object file = Qnil;
1843 struct gcpro gcpro1, gcpro2;
1844 Lisp_Object alist = Qnil;
1846 GCPRO2 (file, alist);
1848 /* Now, convert any file data into inline data. At the end of this,
1849 `data' will contain the inline data (if any) or Qnil, and `file'
1850 will contain the name this data was derived from (if known) or
1853 Note that if we cannot generate any regular inline data, we
1856 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
1859 if (CONSP (file)) /* failure locating filename */
1860 signal_double_file_error ("Opening pixmap file",
1861 "no such file or directory",
1864 if (NILP (file)) /* no conversion necessary */
1865 RETURN_UNGCPRO (inst);
1867 alist = tagged_vector_to_alist (inst);
1870 Lisp_Object data = make_string_from_file (file);
1871 alist = remassq_no_quit (Q_file, alist);
1872 /* there can't be a :data at this point. */
1873 alist = Fcons (Fcons (Q_file, file),
1874 Fcons (Fcons (Q_data, data), alist));
1878 Lisp_Object result = alist_to_tagged_vector (image_type_tag, alist);
1880 RETURN_UNGCPRO (result);
1885 #ifdef HAVE_WINDOW_SYSTEM
1886 /**********************************************************************
1888 **********************************************************************/
1890 /* Check if DATA represents a valid inline XBM spec (i.e. a list
1891 of (width height bits), with checking done on the dimensions).
1892 If not, signal an error. */
1895 check_valid_xbm_inline (Lisp_Object data)
1897 Lisp_Object width, height, bits;
1899 if (!CONSP (data) ||
1900 !CONSP (XCDR (data)) ||
1901 !CONSP (XCDR (XCDR (data))) ||
1902 !NILP (XCDR (XCDR (XCDR (data)))))
1903 signal_simple_error ("Must be list of 3 elements", data);
1905 width = XCAR (data);
1906 height = XCAR (XCDR (data));
1907 bits = XCAR (XCDR (XCDR (data)));
1909 CHECK_STRING (bits);
1911 if (!NATNUMP (width))
1912 signal_simple_error ("Width must be a natural number", width);
1914 if (!NATNUMP (height))
1915 signal_simple_error ("Height must be a natural number", height);
1917 if (((XINT (width) * XINT (height)) / 8) > XSTRING_CHAR_LENGTH (bits))
1918 signal_simple_error ("data is too short for width and height",
1919 vector3 (width, height, bits));
1922 /* Validate method for XBM's. */
1925 xbm_validate (Lisp_Object instantiator)
1927 file_or_data_must_be_present (instantiator);
1930 /* Given a filename that is supposed to contain XBM data, return
1931 the inline representation of it as (width height bits). Return
1932 the hotspot through XHOT and YHOT, if those pointers are not 0.
1933 If there is no hotspot, XHOT and YHOT will contain -1.
1935 If the function fails:
1937 -- if OK_IF_DATA_INVALID is set and the data was invalid,
1939 -- maybe return an error, or return Qnil.
1942 #ifdef HAVE_X_WINDOWS
1943 #include <X11/Xlib.h>
1945 #define XFree(data) free(data)
1949 bitmap_to_lisp_data (Lisp_Object name, int *xhot, int *yhot,
1950 int ok_if_data_invalid)
1955 CONST char *filename_ext;
1957 GET_C_STRING_FILENAME_DATA_ALLOCA (name, filename_ext);
1958 result = read_bitmap_data_from_file (filename_ext, &w, &h,
1961 if (result == BitmapSuccess)
1964 int len = (w + 7) / 8 * h;
1966 retval = list3 (make_int (w), make_int (h),
1967 make_ext_string (data, len, FORMAT_BINARY));
1968 XFree ((char *) data);
1974 case BitmapOpenFailed:
1976 /* should never happen */
1977 signal_double_file_error ("Opening bitmap file",
1978 "no such file or directory",
1981 case BitmapFileInvalid:
1983 if (ok_if_data_invalid)
1985 signal_double_file_error ("Reading bitmap file",
1986 "invalid data in file",
1989 case BitmapNoMemory:
1991 signal_double_file_error ("Reading bitmap file",
1997 signal_double_file_error_2 ("Reading bitmap file",
1998 "unknown error code",
1999 make_int (result), name);
2003 return Qnil; /* not reached */
2007 xbm_mask_file_munging (Lisp_Object alist, Lisp_Object file,
2008 Lisp_Object mask_file, Lisp_Object console_type)
2010 /* This is unclean but it's fairly standard -- a number of the
2011 bitmaps in /usr/include/X11/bitmaps use it -- so we support
2013 if (NILP (mask_file)
2014 /* don't override explicitly specified mask data. */
2015 && NILP (assq_no_quit (Q_mask_data, alist))
2018 mask_file = MAYBE_LISP_CONTYPE_METH
2019 (decode_console_type(console_type, ERROR_ME),
2020 locate_pixmap_file, (concat2 (file, build_string ("Mask"))));
2021 if (NILP (mask_file))
2022 mask_file = MAYBE_LISP_CONTYPE_METH
2023 (decode_console_type(console_type, ERROR_ME),
2024 locate_pixmap_file, (concat2 (file, build_string ("msk"))));
2027 if (!NILP (mask_file))
2029 Lisp_Object mask_data =
2030 bitmap_to_lisp_data (mask_file, 0, 0, 0);
2031 alist = remassq_no_quit (Q_mask_file, alist);
2032 /* there can't be a :mask-data at this point. */
2033 alist = Fcons (Fcons (Q_mask_file, mask_file),
2034 Fcons (Fcons (Q_mask_data, mask_data), alist));
2040 /* Normalize method for XBM's. */
2043 xbm_normalize (Lisp_Object inst, Lisp_Object console_type)
2045 Lisp_Object file = Qnil, mask_file = Qnil;
2046 struct gcpro gcpro1, gcpro2, gcpro3;
2047 Lisp_Object alist = Qnil;
2049 GCPRO3 (file, mask_file, alist);
2051 /* Now, convert any file data into inline data for both the regular
2052 data and the mask data. At the end of this, `data' will contain
2053 the inline data (if any) or Qnil, and `file' will contain
2054 the name this data was derived from (if known) or Qnil.
2055 Likewise for `mask_file' and `mask_data'.
2057 Note that if we cannot generate any regular inline data, we
2060 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
2062 mask_file = potential_pixmap_file_instantiator (inst, Q_mask_file,
2063 Q_mask_data, console_type);
2065 if (CONSP (file)) /* failure locating filename */
2066 signal_double_file_error ("Opening bitmap file",
2067 "no such file or directory",
2070 if (NILP (file) && NILP (mask_file)) /* no conversion necessary */
2071 RETURN_UNGCPRO (inst);
2073 alist = tagged_vector_to_alist (inst);
2078 Lisp_Object data = bitmap_to_lisp_data (file, &xhot, &yhot, 0);
2079 alist = remassq_no_quit (Q_file, alist);
2080 /* there can't be a :data at this point. */
2081 alist = Fcons (Fcons (Q_file, file),
2082 Fcons (Fcons (Q_data, data), alist));
2084 if (xhot != -1 && NILP (assq_no_quit (Q_hotspot_x, alist)))
2085 alist = Fcons (Fcons (Q_hotspot_x, make_int (xhot)),
2087 if (yhot != -1 && NILP (assq_no_quit (Q_hotspot_y, alist)))
2088 alist = Fcons (Fcons (Q_hotspot_y, make_int (yhot)),
2092 alist = xbm_mask_file_munging (alist, file, mask_file, console_type);
2095 Lisp_Object result = alist_to_tagged_vector (Qxbm, alist);
2097 RETURN_UNGCPRO (result);
2103 xbm_possible_dest_types (void)
2106 IMAGE_MONO_PIXMAP_MASK |
2107 IMAGE_COLOR_PIXMAP_MASK |
2115 /**********************************************************************
2117 **********************************************************************/
2120 xface_validate (Lisp_Object instantiator)
2122 file_or_data_must_be_present (instantiator);
2126 xface_normalize (Lisp_Object inst, Lisp_Object console_type)
2128 /* This function can call lisp */
2129 Lisp_Object file = Qnil, mask_file = Qnil;
2130 struct gcpro gcpro1, gcpro2, gcpro3;
2131 Lisp_Object alist = Qnil;
2133 GCPRO3 (file, mask_file, alist);
2135 /* Now, convert any file data into inline data for both the regular
2136 data and the mask data. At the end of this, `data' will contain
2137 the inline data (if any) or Qnil, and `file' will contain
2138 the name this data was derived from (if known) or Qnil.
2139 Likewise for `mask_file' and `mask_data'.
2141 Note that if we cannot generate any regular inline data, we
2144 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
2146 mask_file = potential_pixmap_file_instantiator (inst, Q_mask_file,
2147 Q_mask_data, console_type);
2149 if (CONSP (file)) /* failure locating filename */
2150 signal_double_file_error ("Opening bitmap file",
2151 "no such file or directory",
2154 if (NILP (file) && NILP (mask_file)) /* no conversion necessary */
2155 RETURN_UNGCPRO (inst);
2157 alist = tagged_vector_to_alist (inst);
2160 Lisp_Object data = make_string_from_file (file);
2161 alist = remassq_no_quit (Q_file, alist);
2162 /* there can't be a :data at this point. */
2163 alist = Fcons (Fcons (Q_file, file),
2164 Fcons (Fcons (Q_data, data), alist));
2167 alist = xbm_mask_file_munging (alist, file, mask_file, console_type);
2170 Lisp_Object result = alist_to_tagged_vector (Qxface, alist);
2172 RETURN_UNGCPRO (result);
2177 xface_possible_dest_types (void)
2180 IMAGE_MONO_PIXMAP_MASK |
2181 IMAGE_COLOR_PIXMAP_MASK |
2185 #endif /* HAVE_XFACE */
2190 /**********************************************************************
2192 **********************************************************************/
2195 pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
2201 GET_C_STRING_FILENAME_DATA_ALLOCA (name, fname);
2202 result = XpmReadFileToData (fname, &data);
2204 if (result == XpmSuccess)
2206 Lisp_Object retval = Qnil;
2207 struct buffer *old_buffer = current_buffer;
2208 Lisp_Object temp_buffer =
2209 Fget_buffer_create (build_string (" *pixmap conversion*"));
2211 int height, width, ncolors;
2212 struct gcpro gcpro1, gcpro2, gcpro3;
2213 int speccount = specpdl_depth ();
2215 GCPRO3 (name, retval, temp_buffer);
2217 specbind (Qinhibit_quit, Qt);
2218 set_buffer_internal (XBUFFER (temp_buffer));
2219 Ferase_buffer (Qnil);
2221 buffer_insert_c_string (current_buffer, "/* XPM */\r");
2222 buffer_insert_c_string (current_buffer, "static char *pixmap[] = {\r");
2224 sscanf (data[0], "%d %d %d", &height, &width, &ncolors);
2225 for (elt = 0; elt <= width + ncolors; elt++)
2227 buffer_insert_c_string (current_buffer, "\"");
2228 buffer_insert_c_string (current_buffer, data[elt]);
2230 if (elt < width + ncolors)
2231 buffer_insert_c_string (current_buffer, "\",\r");
2233 buffer_insert_c_string (current_buffer, "\"};\r");
2236 retval = Fbuffer_substring (Qnil, Qnil, Qnil);
2239 set_buffer_internal (old_buffer);
2240 unbind_to (speccount, Qnil);
2242 RETURN_UNGCPRO (retval);
2247 case XpmFileInvalid:
2249 if (ok_if_data_invalid)
2251 signal_image_error ("invalid XPM data in file", name);
2255 signal_double_file_error ("Reading pixmap file",
2256 "out of memory", name);
2260 /* should never happen? */
2261 signal_double_file_error ("Opening pixmap file",
2262 "no such file or directory", name);
2266 signal_double_file_error_2 ("Parsing pixmap file",
2267 "unknown error code",
2268 make_int (result), name);
2273 return Qnil; /* not reached */
2277 check_valid_xpm_color_symbols (Lisp_Object data)
2281 for (rest = data; !NILP (rest); rest = XCDR (rest))
2283 if (!CONSP (rest) ||
2284 !CONSP (XCAR (rest)) ||
2285 !STRINGP (XCAR (XCAR (rest))) ||
2286 (!STRINGP (XCDR (XCAR (rest))) &&
2287 !COLOR_SPECIFIERP (XCDR (XCAR (rest)))))
2288 signal_simple_error ("Invalid color symbol alist", data);
2293 xpm_validate (Lisp_Object instantiator)
2295 file_or_data_must_be_present (instantiator);
2298 Lisp_Object Vxpm_color_symbols;
2301 evaluate_xpm_color_symbols (void)
2303 Lisp_Object rest, results = Qnil;
2304 struct gcpro gcpro1, gcpro2;
2306 GCPRO2 (rest, results);
2307 for (rest = Vxpm_color_symbols; !NILP (rest); rest = XCDR (rest))
2309 Lisp_Object name, value, cons;
2315 CHECK_STRING (name);
2316 value = XCDR (cons);
2318 value = XCAR (value);
2319 value = Feval (value);
2322 if (!STRINGP (value) && !COLOR_SPECIFIERP (value))
2324 ("Result from xpm-color-symbols eval must be nil, string, or color",
2326 results = Fcons (Fcons (name, value), results);
2328 UNGCPRO; /* no more evaluation */
2333 xpm_normalize (Lisp_Object inst, Lisp_Object console_type)
2335 Lisp_Object file = Qnil;
2336 Lisp_Object color_symbols;
2337 struct gcpro gcpro1, gcpro2;
2338 Lisp_Object alist = Qnil;
2340 GCPRO2 (file, alist);
2342 /* Now, convert any file data into inline data. At the end of this,
2343 `data' will contain the inline data (if any) or Qnil, and
2344 `file' will contain the name this data was derived from (if
2347 Note that if we cannot generate any regular inline data, we
2350 file = potential_pixmap_file_instantiator (inst, Q_file, Q_data,
2353 if (CONSP (file)) /* failure locating filename */
2354 signal_double_file_error ("Opening pixmap file",
2355 "no such file or directory",
2358 color_symbols = find_keyword_in_vector_or_given (inst, Q_color_symbols,
2361 if (NILP (file) && !UNBOUNDP (color_symbols))
2362 /* no conversion necessary */
2363 RETURN_UNGCPRO (inst);
2365 alist = tagged_vector_to_alist (inst);
2369 Lisp_Object data = pixmap_to_lisp_data (file, 0);
2370 alist = remassq_no_quit (Q_file, alist);
2371 /* there can't be a :data at this point. */
2372 alist = Fcons (Fcons (Q_file, file),
2373 Fcons (Fcons (Q_data, data), alist));
2376 if (UNBOUNDP (color_symbols))
2378 color_symbols = evaluate_xpm_color_symbols ();
2379 alist = Fcons (Fcons (Q_color_symbols, color_symbols),
2384 Lisp_Object result = alist_to_tagged_vector (Qxpm, alist);
2386 RETURN_UNGCPRO (result);
2391 xpm_possible_dest_types (void)
2394 IMAGE_MONO_PIXMAP_MASK |
2395 IMAGE_COLOR_PIXMAP_MASK |
2399 #endif /* HAVE_XPM */
2402 /****************************************************************************
2403 * Image Specifier Object *
2404 ****************************************************************************/
2406 DEFINE_SPECIFIER_TYPE (image);
2409 image_create (Lisp_Object obj)
2411 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
2413 IMAGE_SPECIFIER_ALLOWED (image) = ~0; /* all are allowed */
2414 IMAGE_SPECIFIER_ATTACHEE (image) = Qnil;
2415 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = Qnil;
2419 image_mark (Lisp_Object obj)
2421 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
2423 mark_object (IMAGE_SPECIFIER_ATTACHEE (image));
2424 mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image));
2428 image_instantiate_cache_result (Lisp_Object locative)
2430 /* locative = (instance instantiator . subtable) */
2431 Fputhash (XCAR (XCDR (locative)), XCAR (locative), XCDR (XCDR (locative)));
2432 free_cons (XCONS (XCDR (locative)));
2433 free_cons (XCONS (locative));
2437 /* Given a specification for an image, return an instance of
2438 the image which matches the given instantiator and which can be
2439 displayed in the given domain. */
2442 image_instantiate (Lisp_Object specifier, Lisp_Object matchspec,
2443 Lisp_Object domain, Lisp_Object instantiator,
2446 Lisp_Object device = DFW_DEVICE (domain);
2447 struct device *d = XDEVICE (device);
2448 int dest_mask = XIMAGE_SPECIFIER_ALLOWED (specifier);
2449 int pointerp = dest_mask & image_instance_type_to_mask (IMAGE_POINTER);
2451 if (IMAGE_INSTANCEP (instantiator))
2453 /* make sure that the image instance's device and type are
2456 if (EQ (device, XIMAGE_INSTANCE_DEVICE (instantiator)))
2459 image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instantiator));
2460 if (mask & dest_mask)
2461 return instantiator;
2463 signal_simple_error ("Type of image instance not allowed here",
2467 signal_simple_error_2 ("Wrong device for image instance",
2468 instantiator, device);
2470 else if (VECTORP (instantiator)
2471 && EQ (XVECTOR_DATA (instantiator)[0], Qinherit))
2473 assert (XVECTOR_LENGTH (instantiator) == 3);
2474 return (FACE_PROPERTY_INSTANCE
2475 (Fget_face (XVECTOR_DATA (instantiator)[2]),
2476 Qbackground_pixmap, domain, 0, depth));
2480 Lisp_Object instance;
2481 Lisp_Object subtable;
2482 Lisp_Object ls3 = Qnil;
2483 Lisp_Object pointer_fg = Qnil;
2484 Lisp_Object pointer_bg = Qnil;
2488 pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
2489 pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
2490 ls3 = list3 (instantiator, pointer_fg, pointer_bg);
2493 /* First look in the hash table. */
2494 subtable = Fgethash (make_int (dest_mask), d->image_instance_cache,
2496 if (UNBOUNDP (subtable))
2498 /* For the image instance cache, we do comparisons with EQ rather
2499 than with EQUAL, as we do for color and font names.
2502 1) pixmap data can be very long, and thus the hashing and
2503 comparing will take awhile.
2504 2) It's not so likely that we'll run into things that are EQUAL
2505 but not EQ (that can happen a lot with faces, because their
2506 specifiers are copied around); but pixmaps tend not to be
2509 However, if the image-instance could be a pointer, we have to
2510 use EQUAL because we massaged the instantiator into a cons3
2511 also containing the foreground and background of the
2515 subtable = make_lisp_hash_table (20,
2516 pointerp ? HASH_TABLE_KEY_CAR_WEAK
2517 : HASH_TABLE_KEY_WEAK,
2518 pointerp ? HASH_TABLE_EQUAL
2520 Fputhash (make_int (dest_mask), subtable,
2521 d->image_instance_cache);
2522 instance = Qunbound;
2526 instance = Fgethash (pointerp ? ls3 : instantiator,
2527 subtable, Qunbound);
2528 /* subwindows have a per-window cache and have to be treated
2529 differently. dest_mask can be a bitwise OR of all image
2530 types so we will only catch someone possibly trying to
2531 instantiate a subwindow type thing. Unfortunately, this
2532 will occur most of the time so this probably slows things
2533 down. But with the current design I don't see anyway
2535 if (UNBOUNDP (instance)
2537 dest_mask & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
2539 if (!WINDOWP (domain))
2540 signal_simple_error ("Can't instantiate subwindow outside a window",
2542 instance = Fgethash (instantiator,
2543 XWINDOW (domain)->subwindow_instance_cache,
2548 if (UNBOUNDP (instance))
2550 Lisp_Object locative =
2552 noseeum_cons (pointerp ? ls3 : instantiator,
2554 int speccount = specpdl_depth ();
2556 /* make sure we cache the failures, too.
2557 Use an unwind-protect to catch such errors.
2558 If we fail, the unwind-protect records nil in
2559 the hash table. If we succeed, we change the
2560 car of the locative to the resulting instance,
2561 which gets recorded instead. */
2562 record_unwind_protect (image_instantiate_cache_result,
2564 instance = instantiate_image_instantiator (device,
2567 pointer_fg, pointer_bg,
2570 Fsetcar (locative, instance);
2571 /* only after the image has been instantiated do we know
2572 whether we need to put it in the per-window image instance
2574 if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
2576 (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
2578 if (!WINDOWP (domain))
2579 signal_simple_error ("Can't instantiate subwindow outside a window",
2582 Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache );
2584 unbind_to (speccount, Qnil);
2589 if (NILP (instance))
2590 signal_simple_error ("Can't instantiate image (probably cached)",
2596 return Qnil; /* not reached */
2599 /* Validate an image instantiator. */
2602 image_validate (Lisp_Object instantiator)
2604 if (IMAGE_INSTANCEP (instantiator) || STRINGP (instantiator))
2606 else if (VECTORP (instantiator))
2608 Lisp_Object *elt = XVECTOR_DATA (instantiator);
2609 int instantiator_len = XVECTOR_LENGTH (instantiator);
2610 struct image_instantiator_methods *meths;
2611 Lisp_Object already_seen = Qnil;
2612 struct gcpro gcpro1;
2615 if (instantiator_len < 1)
2616 signal_simple_error ("Vector length must be at least 1",
2619 meths = decode_image_instantiator_format (elt[0], ERROR_ME);
2620 if (!(instantiator_len & 1))
2622 ("Must have alternating keyword/value pairs", instantiator);
2624 GCPRO1 (already_seen);
2626 for (i = 1; i < instantiator_len; i += 2)
2628 Lisp_Object keyword = elt[i];
2629 Lisp_Object value = elt[i+1];
2632 CHECK_SYMBOL (keyword);
2633 if (!SYMBOL_IS_KEYWORD (keyword))
2634 signal_simple_error ("Symbol must begin with a colon", keyword);
2636 for (j = 0; j < Dynarr_length (meths->keywords); j++)
2637 if (EQ (keyword, Dynarr_at (meths->keywords, j).keyword))
2640 if (j == Dynarr_length (meths->keywords))
2641 signal_simple_error ("Unrecognized keyword", keyword);
2643 if (!Dynarr_at (meths->keywords, j).multiple_p)
2645 if (!NILP (memq_no_quit (keyword, already_seen)))
2647 ("Keyword may not appear more than once", keyword);
2648 already_seen = Fcons (keyword, already_seen);
2651 (Dynarr_at (meths->keywords, j).validate) (value);
2656 MAYBE_IIFORMAT_METH (meths, validate, (instantiator));
2659 signal_simple_error ("Must be string or vector", instantiator);
2663 image_after_change (Lisp_Object specifier, Lisp_Object locale)
2665 Lisp_Object attachee =
2666 IMAGE_SPECIFIER_ATTACHEE (XIMAGE_SPECIFIER (specifier));
2667 Lisp_Object property =
2668 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (XIMAGE_SPECIFIER (specifier));
2669 if (FACEP (attachee))
2670 face_property_was_changed (attachee, property, locale);
2671 else if (GLYPHP (attachee))
2672 glyph_property_was_changed (attachee, property, locale);
2676 set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph,
2677 Lisp_Object property)
2679 struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
2681 IMAGE_SPECIFIER_ATTACHEE (image) = face_or_glyph;
2682 IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image) = property;
2686 image_going_to_add (Lisp_Object specifier, Lisp_Object locale,
2687 Lisp_Object tag_set, Lisp_Object instantiator)
2689 Lisp_Object possible_console_types = Qnil;
2691 Lisp_Object retlist = Qnil;
2692 struct gcpro gcpro1, gcpro2;
2694 LIST_LOOP (rest, Vconsole_type_list)
2696 Lisp_Object contype = XCAR (rest);
2697 if (!NILP (memq_no_quit (contype, tag_set)))
2698 possible_console_types = Fcons (contype, possible_console_types);
2701 if (XINT (Flength (possible_console_types)) > 1)
2702 /* two conflicting console types specified */
2705 if (NILP (possible_console_types))
2706 possible_console_types = Vconsole_type_list;
2708 GCPRO2 (retlist, possible_console_types);
2710 LIST_LOOP (rest, possible_console_types)
2712 Lisp_Object contype = XCAR (rest);
2713 Lisp_Object newinst = call_with_suspended_errors
2714 ((lisp_fn_t) normalize_image_instantiator,
2715 Qnil, Qimage, ERROR_ME_NOT, 3, instantiator, contype,
2716 make_int (XIMAGE_SPECIFIER_ALLOWED (specifier)));
2718 if (!NILP (newinst))
2721 if (NILP (memq_no_quit (contype, tag_set)))
2722 newtag = Fcons (contype, tag_set);
2725 retlist = Fcons (Fcons (newtag, newinst), retlist);
2734 DEFUN ("image-specifier-p", Fimage_specifier_p, 1, 1, 0, /*
2735 Return non-nil if OBJECT is an image specifier.
2737 An image specifier is used for images (pixmaps and the like). It is used
2738 to describe the actual image in a glyph. It is instanced as an image-
2741 Image instantiators come in many formats: `xbm', `xpm', `gif', `jpeg',
2742 etc. This describes the format of the data describing the image. The
2743 resulting image instances also come in many types -- `mono-pixmap',
2744 `color-pixmap', `text', `pointer', etc. This refers to the behavior of
2745 the image and the sorts of places it can appear. (For example, a
2746 color-pixmap image has fixed colors specified for it, while a
2747 mono-pixmap image comes in two unspecified shades "foreground" and
2748 "background" that are determined from the face of the glyph or
2749 surrounding text; a text image appears as a string of text and has an
2750 unspecified foreground, background, and font; a pointer image behaves
2751 like a mono-pixmap image but can only be used as a mouse pointer
2752 \[mono-pixmap images cannot be used as mouse pointers]; etc.) It is
2753 important to keep the distinction between image instantiator format and
2754 image instance type in mind. Typically, a given image instantiator
2755 format can result in many different image instance types (for example,
2756 `xpm' can be instanced as `color-pixmap', `mono-pixmap', or `pointer';
2757 whereas `cursor-font' can be instanced only as `pointer'), and a
2758 particular image instance type can be generated by many different
2759 image instantiator formats (e.g. `color-pixmap' can be generated by `xpm',
2760 `gif', `jpeg', etc.).
2762 See `make-image-instance' for a more detailed discussion of image
2765 An image instantiator should be a string or a vector of the form
2767 [FORMAT :KEYWORD VALUE ...]
2769 i.e. a format symbol followed by zero or more alternating keyword-value
2770 pairs. FORMAT should be one of
2773 (Don't display anything; no keywords are valid for this.
2774 Can only be instanced as `nothing'.)
2776 (Display this image as a text string. Can only be instanced
2777 as `text', although support for instancing as `mono-pixmap'
2780 (Display this image as a text string, with replaceable fields;
2781 not currently implemented.)
2783 (An X bitmap; only if X or Windows support was compiled into this XEmacs.
2784 Can be instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
2786 (An XPM pixmap; only if XPM support was compiled into this XEmacs.
2787 Can be instanced as `color-pixmap', `mono-pixmap', or `pointer'.)
2789 (An X-Face bitmap, used to encode people's faces in e-mail messages;
2790 only if X-Face support was compiled into this XEmacs. Can be
2791 instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
2793 (A GIF87 or GIF89 image; only if GIF support was compiled into this
2794 XEmacs. NOTE: only the first frame of animated gifs will be displayed.
2795 Can be instanced as `color-pixmap'.)
2797 (A JPEG image; only if JPEG support was compiled into this XEmacs.
2798 Can be instanced as `color-pixmap'.)
2800 (A PNG image; only if PNG support was compiled into this XEmacs.
2801 Can be instanced as `color-pixmap'.)
2803 (A TIFF image; only if TIFF support was compiled into this XEmacs.
2804 Can be instanced as `color-pixmap'.)
2806 (One of the standard cursor-font names, such as "watch" or
2807 "right_ptr" under X. Under X, this is, more specifically, any
2808 of the standard cursor names from appendix B of the Xlib manual
2809 [also known as the file <X11/cursorfont.h>] minus the XC_ prefix.
2810 On other window systems, the valid names will be specific to the
2811 type of window system. Can only be instanced as `pointer'.)
2813 (A glyph from a font; i.e. the name of a font, and glyph index into it
2814 of the form "FONT fontname index [[mask-font] mask-index]".
2815 Currently can only be instanced as `pointer', although this should
2818 (An embedded windowing system window.)
2820 (A text editing widget glyph.)
2822 (A button widget glyph; either a push button, radio button or toggle button.)
2824 (A tab widget glyph; a series of user selectable tabs.)
2826 (A sliding widget glyph, for showing progress.)
2828 (A drop list of selectable items in a widget glyph, for editing text.)
2830 (A static, text-only, widget glyph; for displaying text.)
2832 (A folding widget glyph.)
2834 (XEmacs tries to guess what format the data is in. If X support
2835 exists, the data string will be checked to see if it names a filename.
2836 If so, and this filename contains XBM or XPM data, the appropriate
2837 sort of pixmap or pointer will be created. [This includes picking up
2838 any specified hotspot or associated mask file.] Otherwise, if `pointer'
2839 is one of the allowable image-instance types and the string names a
2840 valid cursor-font name, the image will be created as a pointer.
2841 Otherwise, the image will be displayed as text. If no X support
2842 exists, the image will always be displayed as text.)
2844 Inherit from the background-pixmap property of a face.
2846 The valid keywords are:
2849 (Inline data. For most formats above, this should be a string. For
2850 XBM images, this should be a list of three elements: width, height, and
2851 a string of bit data. This keyword is not valid for instantiator
2852 formats `nothing' and `inherit'.)
2854 (Data is contained in a file. The value is the name of this file.
2855 If both :data and :file are specified, the image is created from
2856 what is specified in :data and the string in :file becomes the
2857 value of the `image-instance-file-name' function when applied to
2858 the resulting image-instance. This keyword is not valid for
2859 instantiator formats `nothing', `string', `formatted-string',
2860 `cursor-font', `font', `autodetect', and `inherit'.)
2863 (For `xbm', `xface', `cursor-font', `widget' and `font'. These keywords
2864 allow you to explicitly specify foreground and background colors.
2865 The argument should be anything acceptable to `make-color-instance'.
2866 This will cause what would be a `mono-pixmap' to instead be colorized
2867 as a two-color color-pixmap, and specifies the foreground and/or
2868 background colors for a pointer instead of black and white.)
2870 (For `xbm' and `xface'. This specifies a mask to be used with the
2871 bitmap. The format is a list of width, height, and bits, like for
2874 (For `xbm' and `xface'. This specifies a file containing the mask data.
2875 If neither a mask file nor inline mask data is given for an XBM image,
2876 and the XBM image comes from a file, XEmacs will look for a mask file
2877 with the same name as the image file but with "Mask" or "msk"
2878 appended. For example, if you specify the XBM file "left_ptr"
2879 [usually located in "/usr/include/X11/bitmaps"], the associated
2880 mask file "left_ptrmsk" will automatically be picked up.)
2883 (For `xbm' and `xface'. These keywords specify a hotspot if the image
2884 is instantiated as a `pointer'. Note that if the XBM image file
2885 specifies a hotspot, it will automatically be picked up if no
2886 explicit hotspot is given.)
2888 (Only for `xpm'. This specifies an alist that maps strings
2889 that specify symbolic color names to the actual color to be used
2890 for that symbolic color (in the form of a string or a color-specifier
2891 object). If this is not specified, the contents of `xpm-color-symbols'
2892 are used to generate the alist.)
2894 (Only for `inherit'. This specifies the face to inherit from.
2895 For widget glyphs this also specifies the face to use for
2896 display. It defaults to gui-element-face.)
2898 Keywords accepted as menu item specs are also accepted by widget
2899 glyphs. These are `:selected', `:active', `:suffix', `:keys',
2900 `:style', `:filter', `:config', `:included', `:key-sequence',
2901 `:accelerator', `:label' and `:callback'.
2903 If instead of a vector, the instantiator is a string, it will be
2904 converted into a vector by looking it up according to the specs in the
2905 `console-type-image-conversion-list' (q.v.) for the console type of
2906 the domain (usually a window; sometimes a frame or device) over which
2907 the image is being instantiated.
2909 If the instantiator specifies data from a file, the data will be read
2910 in at the time that the instantiator is added to the image (which may
2911 be well before when the image is actually displayed), and the
2912 instantiator will be converted into one of the inline-data forms, with
2913 the filename retained using a :file keyword. This implies that the
2914 file must exist when the instantiator is added to the image, but does
2915 not need to exist at any other time (e.g. it may safely be a temporary
2920 return IMAGE_SPECIFIERP (object) ? Qt : Qnil;
2924 /****************************************************************************
2926 ****************************************************************************/
2929 mark_glyph (Lisp_Object obj)
2931 struct Lisp_Glyph *glyph = XGLYPH (obj);
2933 mark_object (glyph->image);
2934 mark_object (glyph->contrib_p);
2935 mark_object (glyph->baseline);
2936 mark_object (glyph->face);
2938 return glyph->plist;
2942 print_glyph (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
2944 struct Lisp_Glyph *glyph = XGLYPH (obj);
2948 error ("printing unreadable object #<glyph 0x%x>", glyph->header.uid);
2950 write_c_string ("#<glyph (", printcharfun);
2951 print_internal (Fglyph_type (obj), printcharfun, 0);
2952 write_c_string (") ", printcharfun);
2953 print_internal (glyph->image, printcharfun, 1);
2954 sprintf (buf, "0x%x>", glyph->header.uid);
2955 write_c_string (buf, printcharfun);
2958 /* Glyphs are equal if all of their display attributes are equal. We
2959 don't compare names or doc-strings, because that would make equal
2962 This isn't concerned with "unspecified" attributes, that's what
2963 #'glyph-differs-from-default-p is for. */
2965 glyph_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
2967 struct Lisp_Glyph *g1 = XGLYPH (obj1);
2968 struct Lisp_Glyph *g2 = XGLYPH (obj2);
2972 return (internal_equal (g1->image, g2->image, depth) &&
2973 internal_equal (g1->contrib_p, g2->contrib_p, depth) &&
2974 internal_equal (g1->baseline, g2->baseline, depth) &&
2975 internal_equal (g1->face, g2->face, depth) &&
2976 !plists_differ (g1->plist, g2->plist, 0, 0, depth + 1));
2979 static unsigned long
2980 glyph_hash (Lisp_Object obj, int depth)
2984 /* No need to hash all of the elements; that would take too long.
2985 Just hash the most common ones. */
2986 return HASH2 (internal_hash (XGLYPH (obj)->image, depth),
2987 internal_hash (XGLYPH (obj)->face, depth));
2991 glyph_getprop (Lisp_Object obj, Lisp_Object prop)
2993 struct Lisp_Glyph *g = XGLYPH (obj);
2995 if (EQ (prop, Qimage)) return g->image;
2996 if (EQ (prop, Qcontrib_p)) return g->contrib_p;
2997 if (EQ (prop, Qbaseline)) return g->baseline;
2998 if (EQ (prop, Qface)) return g->face;
3000 return external_plist_get (&g->plist, prop, 0, ERROR_ME);
3004 glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
3006 if (EQ (prop, Qimage) ||
3007 EQ (prop, Qcontrib_p) ||
3008 EQ (prop, Qbaseline))
3011 if (EQ (prop, Qface))
3013 XGLYPH (obj)->face = Fget_face (value);
3017 external_plist_put (&XGLYPH (obj)->plist, prop, value, 0, ERROR_ME);
3022 glyph_remprop (Lisp_Object obj, Lisp_Object prop)
3024 if (EQ (prop, Qimage) ||
3025 EQ (prop, Qcontrib_p) ||
3026 EQ (prop, Qbaseline))
3029 if (EQ (prop, Qface))
3031 XGLYPH (obj)->face = Qnil;
3035 return external_remprop (&XGLYPH (obj)->plist, prop, 0, ERROR_ME);
3039 glyph_plist (Lisp_Object obj)
3041 struct Lisp_Glyph *glyph = XGLYPH (obj);
3042 Lisp_Object result = glyph->plist;
3044 result = cons3 (Qface, glyph->face, result);
3045 result = cons3 (Qbaseline, glyph->baseline, result);
3046 result = cons3 (Qcontrib_p, glyph->contrib_p, result);
3047 result = cons3 (Qimage, glyph->image, result);
3052 static const struct lrecord_description glyph_description[] = {
3053 { XD_LISP_OBJECT, offsetof(struct Lisp_Glyph, image), 5 },
3057 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("glyph", glyph,
3058 mark_glyph, print_glyph, 0,
3059 glyph_equal, glyph_hash, glyph_description,
3060 glyph_getprop, glyph_putprop,
3061 glyph_remprop, glyph_plist,
3065 allocate_glyph (enum glyph_type type,
3066 void (*after_change) (Lisp_Object glyph, Lisp_Object property,
3067 Lisp_Object locale))
3069 /* This function can GC */
3070 Lisp_Object obj = Qnil;
3071 struct Lisp_Glyph *g =
3072 alloc_lcrecord_type (struct Lisp_Glyph, &lrecord_glyph);
3075 g->image = Fmake_specifier (Qimage); /* This function can GC */
3080 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3081 IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK
3082 | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
3083 | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK
3084 | IMAGE_LAYOUT_MASK;
3087 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3088 IMAGE_NOTHING_MASK | IMAGE_POINTER_MASK;
3091 XIMAGE_SPECIFIER_ALLOWED (g->image) =
3092 IMAGE_NOTHING_MASK | IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK;
3098 /* I think Fmake_specifier can GC. I think set_specifier_fallback can GC. */
3099 /* We're getting enough reports of odd behavior in this area it seems */
3100 /* best to GCPRO everything. */
3102 Lisp_Object tem1 = list1 (Fcons (Qnil, Vthe_nothing_vector));
3103 Lisp_Object tem2 = list1 (Fcons (Qnil, Qt));
3104 Lisp_Object tem3 = list1 (Fcons (Qnil, Qnil));
3105 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3107 GCPRO4 (obj, tem1, tem2, tem3);
3109 set_specifier_fallback (g->image, tem1);
3110 g->contrib_p = Fmake_specifier (Qboolean);
3111 set_specifier_fallback (g->contrib_p, tem2);
3112 /* #### should have a specifier for the following */
3113 g->baseline = Fmake_specifier (Qgeneric);
3114 set_specifier_fallback (g->baseline, tem3);
3117 g->after_change = after_change;
3120 set_image_attached_to (g->image, obj, Qimage);
3127 static enum glyph_type
3128 decode_glyph_type (Lisp_Object type, Error_behavior errb)
3131 return GLYPH_BUFFER;
3133 if (ERRB_EQ (errb, ERROR_ME))
3134 CHECK_SYMBOL (type);
3136 if (EQ (type, Qbuffer)) return GLYPH_BUFFER;
3137 if (EQ (type, Qpointer)) return GLYPH_POINTER;
3138 if (EQ (type, Qicon)) return GLYPH_ICON;
3140 maybe_signal_simple_error ("Invalid glyph type", type, Qimage, errb);
3142 return GLYPH_UNKNOWN;
3146 valid_glyph_type_p (Lisp_Object type)
3148 return !NILP (memq_no_quit (type, Vglyph_type_list));
3151 DEFUN ("valid-glyph-type-p", Fvalid_glyph_type_p, 1, 1, 0, /*
3152 Given a GLYPH-TYPE, return non-nil if it is valid.
3153 Valid types are `buffer', `pointer', and `icon'.
3157 return valid_glyph_type_p (glyph_type) ? Qt : Qnil;
3160 DEFUN ("glyph-type-list", Fglyph_type_list, 0, 0, 0, /*
3161 Return a list of valid glyph types.
3165 return Fcopy_sequence (Vglyph_type_list);
3168 DEFUN ("make-glyph-internal", Fmake_glyph_internal, 0, 1, 0, /*
3169 Create and return a new uninitialized glyph or type TYPE.
3171 TYPE specifies the type of the glyph; this should be one of `buffer',
3172 `pointer', or `icon', and defaults to `buffer'. The type of the glyph
3173 specifies in which contexts the glyph can be used, and controls the
3174 allowable image types into which the glyph's image can be
3177 `buffer' glyphs can be used as the begin-glyph or end-glyph of an
3178 extent, in the modeline, and in the toolbar. Their image can be
3179 instantiated as `nothing', `mono-pixmap', `color-pixmap', `text',
3182 `pointer' glyphs can be used to specify the mouse pointer. Their
3183 image can be instantiated as `pointer'.
3185 `icon' glyphs can be used to specify the icon used when a frame is
3186 iconified. Their image can be instantiated as `mono-pixmap' and
3191 enum glyph_type typeval = decode_glyph_type (type, ERROR_ME);
3192 return allocate_glyph (typeval, 0);
3195 DEFUN ("glyphp", Fglyphp, 1, 1, 0, /*
3196 Return non-nil if OBJECT is a glyph.
3198 A glyph is an object used for pixmaps and the like. It is used
3199 in begin-glyphs and end-glyphs attached to extents, in marginal and textual
3200 annotations, in overlay arrows (overlay-arrow-* variables), in toolbar
3201 buttons, and the like. Its image is described using an image specifier --
3202 see `image-specifier-p'.
3206 return GLYPHP (object) ? Qt : Qnil;
3209 DEFUN ("glyph-type", Fglyph_type, 1, 1, 0, /*
3210 Return the type of the given glyph.
3211 The return value will be one of 'buffer, 'pointer, or 'icon.
3215 CHECK_GLYPH (glyph);
3216 switch (XGLYPH_TYPE (glyph))
3219 case GLYPH_BUFFER: return Qbuffer;
3220 case GLYPH_POINTER: return Qpointer;
3221 case GLYPH_ICON: return Qicon;
3225 /*****************************************************************************
3228 Return the width of the given GLYPH on the given WINDOW. If the
3229 instance is a string then the width is calculated using the font of
3230 the given FACE, unless a face is defined by the glyph itself.
3231 ****************************************************************************/
3233 glyph_width (Lisp_Object glyph_or_image, Lisp_Object frame_face,
3234 face_index window_findex, Lisp_Object window)
3236 Lisp_Object instance = glyph_or_image;
3237 Lisp_Object frame = XWINDOW (window)->frame;
3239 /* #### We somehow need to distinguish between the user causing this
3240 error condition and a bug causing it. */
3241 if (GLYPHP (glyph_or_image))
3242 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
3244 if (!IMAGE_INSTANCEP (instance))
3247 switch (XIMAGE_INSTANCE_TYPE (instance))
3251 Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance);
3252 Lisp_Object private_face = Qnil;
3254 if (GLYPHP (glyph_or_image))
3255 private_face = XGLYPH_FACE(glyph_or_image);
3257 if (!NILP (private_face))
3258 return redisplay_frame_text_width_string (XFRAME (frame),
3262 if (!NILP (frame_face))
3263 return redisplay_frame_text_width_string (XFRAME (frame),
3267 return redisplay_text_width_string (XWINDOW (window),
3272 case IMAGE_MONO_PIXMAP:
3273 case IMAGE_COLOR_PIXMAP:
3275 return XIMAGE_INSTANCE_PIXMAP_WIDTH (instance);
3280 case IMAGE_SUBWINDOW:
3283 return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance);
3291 DEFUN ("glyph-width", Fglyph_width, 1, 2, 0, /*
3292 Return the width of GLYPH on WINDOW.
3293 This may not be exact as it does not take into account all of the context
3294 that redisplay will.
3298 XSETWINDOW (window, decode_window (window));
3299 CHECK_GLYPH (glyph);
3301 return make_int (glyph_width (glyph, Qnil, DEFAULT_INDEX, window));
3304 #define RETURN_ASCENT 0
3305 #define RETURN_DESCENT 1
3306 #define RETURN_HEIGHT 2
3309 glyph_image_instance (Lisp_Object glyph, Lisp_Object domain,
3310 Error_behavior errb, int no_quit)
3312 Lisp_Object specifier = GLYPH_IMAGE (XGLYPH (glyph));
3314 /* This can never return Qunbound. All glyphs have 'nothing as
3316 return specifier_instance (specifier, Qunbound, domain, errb, no_quit, 0,
3320 static unsigned short
3321 glyph_height_internal (Lisp_Object glyph_or_image, Lisp_Object frame_face,
3322 face_index window_findex, Lisp_Object window,
3325 Lisp_Object instance = glyph_or_image;
3326 Lisp_Object frame = XWINDOW (window)->frame;
3328 if (GLYPHP (glyph_or_image))
3329 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
3331 if (!IMAGE_INSTANCEP (instance))
3334 switch (XIMAGE_INSTANCE_TYPE (instance))
3338 struct font_metric_info fm;
3339 Lisp_Object string = XIMAGE_INSTANCE_TEXT_STRING (instance);
3340 unsigned char charsets[NUM_LEADING_BYTES];
3341 struct face_cachel frame_cachel;
3342 struct face_cachel *cachel;
3344 find_charsets_in_bufbyte_string (charsets,
3345 XSTRING_DATA (string),
3346 XSTRING_LENGTH (string));
3348 if (!NILP (frame_face))
3350 reset_face_cachel (&frame_cachel);
3351 update_face_cachel_data (&frame_cachel, frame, frame_face);
3352 cachel = &frame_cachel;
3355 cachel = WINDOW_FACE_CACHEL (XWINDOW (window), window_findex);
3356 ensure_face_cachel_complete (cachel, window, charsets);
3358 face_cachel_charset_font_metric_info (cachel, charsets, &fm);
3362 case RETURN_ASCENT: return fm.ascent;
3363 case RETURN_DESCENT: return fm.descent;
3364 case RETURN_HEIGHT: return fm.ascent + fm.descent;
3367 return 0; /* not reached */
3371 case IMAGE_MONO_PIXMAP:
3372 case IMAGE_COLOR_PIXMAP:
3374 /* #### Ugh ugh ugh -- temporary crap */
3375 if (function == RETURN_ASCENT || function == RETURN_HEIGHT)
3376 return XIMAGE_INSTANCE_PIXMAP_HEIGHT (instance);
3383 case IMAGE_SUBWINDOW:
3386 /* #### Ugh ugh ugh -- temporary crap */
3387 if (function == RETURN_ASCENT || function == RETURN_HEIGHT)
3388 return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance);
3399 glyph_ascent (Lisp_Object glyph, Lisp_Object frame_face,
3400 face_index window_findex, Lisp_Object window)
3402 return glyph_height_internal (glyph, frame_face, window_findex, window,
3407 glyph_descent (Lisp_Object glyph, Lisp_Object frame_face,
3408 face_index window_findex, Lisp_Object window)
3410 return glyph_height_internal (glyph, frame_face, window_findex, window,
3414 /* strictly a convenience function. */
3416 glyph_height (Lisp_Object glyph, Lisp_Object frame_face,
3417 face_index window_findex, Lisp_Object window)
3419 return glyph_height_internal (glyph, frame_face, window_findex, window,
3423 DEFUN ("glyph-ascent", Fglyph_ascent, 1, 2, 0, /*
3424 Return the ascent value of GLYPH on WINDOW.
3425 This may not be exact as it does not take into account all of the context
3426 that redisplay will.
3430 XSETWINDOW (window, decode_window (window));
3431 CHECK_GLYPH (glyph);
3433 return make_int (glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window));
3436 DEFUN ("glyph-descent", Fglyph_descent, 1, 2, 0, /*
3437 Return the descent value of GLYPH on WINDOW.
3438 This may not be exact as it does not take into account all of the context
3439 that redisplay will.
3443 XSETWINDOW (window, decode_window (window));
3444 CHECK_GLYPH (glyph);
3446 return make_int (glyph_descent (glyph, Qnil, DEFAULT_INDEX, window));
3449 /* This is redundant but I bet a lot of people expect it to exist. */
3450 DEFUN ("glyph-height", Fglyph_height, 1, 2, 0, /*
3451 Return the height of GLYPH on WINDOW.
3452 This may not be exact as it does not take into account all of the context
3453 that redisplay will.
3457 XSETWINDOW (window, decode_window (window));
3458 CHECK_GLYPH (glyph);
3460 return make_int (glyph_height (glyph, Qnil, DEFAULT_INDEX, window));
3463 #undef RETURN_ASCENT
3464 #undef RETURN_DESCENT
3465 #undef RETURN_HEIGHT
3468 glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window)
3470 Lisp_Object instance = glyph_or_image;
3472 if (GLYPHP (glyph_or_image))
3473 instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
3475 return XIMAGE_INSTANCE_DIRTYP (instance);
3479 set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty)
3481 Lisp_Object instance = glyph_or_image;
3483 if (!NILP (glyph_or_image))
3485 if (GLYPHP (glyph_or_image))
3487 instance = glyph_image_instance (glyph_or_image, window,
3489 XGLYPH_DIRTYP (glyph_or_image) = dirty;
3492 XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
3496 /* #### do we need to cache this info to speed things up? */
3499 glyph_baseline (Lisp_Object glyph, Lisp_Object domain)
3501 if (!GLYPHP (glyph))
3505 Lisp_Object retval =
3506 specifier_instance_no_quit (GLYPH_BASELINE (XGLYPH (glyph)),
3507 /* #### look into ERROR_ME_NOT */
3508 Qunbound, domain, ERROR_ME_NOT,
3510 if (!NILP (retval) && !INTP (retval))
3512 else if (INTP (retval))
3514 if (XINT (retval) < 0)
3516 if (XINT (retval) > 100)
3517 retval = make_int (100);
3524 glyph_face (Lisp_Object glyph, Lisp_Object domain)
3526 /* #### Domain parameter not currently used but it will be */
3527 return GLYPHP (glyph) ? GLYPH_FACE (XGLYPH (glyph)) : Qnil;
3531 glyph_contrib_p (Lisp_Object glyph, Lisp_Object domain)
3533 if (!GLYPHP (glyph))
3536 return !NILP (specifier_instance_no_quit
3537 (GLYPH_CONTRIB_P (XGLYPH (glyph)), Qunbound, domain,
3538 /* #### look into ERROR_ME_NOT */
3539 ERROR_ME_NOT, 0, Qzero));
3543 glyph_property_was_changed (Lisp_Object glyph, Lisp_Object property,
3546 if (XGLYPH (glyph)->after_change)
3547 (XGLYPH (glyph)->after_change) (glyph, property, locale);
3551 /*****************************************************************************
3552 * glyph cachel functions *
3553 *****************************************************************************/
3556 #### All of this is 95% copied from face cachels.
3557 Consider consolidating.
3561 mark_glyph_cachels (glyph_cachel_dynarr *elements)
3568 for (elt = 0; elt < Dynarr_length (elements); elt++)
3570 struct glyph_cachel *cachel = Dynarr_atp (elements, elt);
3571 mark_object (cachel->glyph);
3576 update_glyph_cachel_data (struct window *w, Lisp_Object glyph,
3577 struct glyph_cachel *cachel)
3579 if (!cachel->updated || NILP (cachel->glyph) || !EQ (cachel->glyph, glyph)
3580 || XGLYPH_DIRTYP (cachel->glyph))
3582 Lisp_Object window, instance;
3584 XSETWINDOW (window, w);
3586 cachel->glyph = glyph;
3587 /* Speed things up slightly by grabbing the glyph instantiation
3588 and passing it to the size functions. */
3589 instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
3590 cachel->dirty = XGLYPH_DIRTYP (glyph) = glyph_dirty_p (glyph, window);
3591 cachel->width = glyph_width (instance, Qnil, DEFAULT_INDEX, window);
3592 cachel->ascent = glyph_ascent (instance, Qnil, DEFAULT_INDEX, window);
3593 cachel->descent = glyph_descent (instance, Qnil, DEFAULT_INDEX, window);
3596 cachel->updated = 1;
3600 add_glyph_cachel (struct window *w, Lisp_Object glyph)
3602 struct glyph_cachel new_cachel;
3605 new_cachel.glyph = Qnil;
3607 update_glyph_cachel_data (w, glyph, &new_cachel);
3608 Dynarr_add (w->glyph_cachels, new_cachel);
3612 get_glyph_cachel_index (struct window *w, Lisp_Object glyph)
3619 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
3621 struct glyph_cachel *cachel =
3622 Dynarr_atp (w->glyph_cachels, elt);
3624 if (EQ (cachel->glyph, glyph) && !NILP (glyph))
3626 update_glyph_cachel_data (w, glyph, cachel);
3631 /* If we didn't find the glyph, add it and then return its index. */
3632 add_glyph_cachel (w, glyph);
3637 reset_glyph_cachels (struct window *w)
3639 Dynarr_reset (w->glyph_cachels);
3640 get_glyph_cachel_index (w, Vcontinuation_glyph);
3641 get_glyph_cachel_index (w, Vtruncation_glyph);
3642 get_glyph_cachel_index (w, Vhscroll_glyph);
3643 get_glyph_cachel_index (w, Vcontrol_arrow_glyph);
3644 get_glyph_cachel_index (w, Voctal_escape_glyph);
3645 get_glyph_cachel_index (w, Vinvisible_text_glyph);
3649 mark_glyph_cachels_as_not_updated (struct window *w)
3653 /* We need to have a dirty flag to tell if the glyph has changed.
3654 We can check to see if each glyph variable is actually a
3655 completely different glyph, though. */
3656 #define FROB(glyph_obj, gindex) \
3657 update_glyph_cachel_data (w, glyph_obj, \
3658 Dynarr_atp (w->glyph_cachels, gindex))
3660 FROB (Vcontinuation_glyph, CONT_GLYPH_INDEX);
3661 FROB (Vtruncation_glyph, TRUN_GLYPH_INDEX);
3662 FROB (Vhscroll_glyph, HSCROLL_GLYPH_INDEX);
3663 FROB (Vcontrol_arrow_glyph, CONTROL_GLYPH_INDEX);
3664 FROB (Voctal_escape_glyph, OCT_ESC_GLYPH_INDEX);
3665 FROB (Vinvisible_text_glyph, INVIS_GLYPH_INDEX);
3668 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
3670 Dynarr_atp (w->glyph_cachels, elt)->updated = 0;
3674 /* Unset the dirty bit on all the glyph cachels that have it. */
3676 mark_glyph_cachels_as_clean (struct window* w)
3680 XSETWINDOW (window, w);
3681 for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
3683 struct glyph_cachel *cachel = Dynarr_atp (w->glyph_cachels, elt);
3685 set_glyph_dirty_p (cachel->glyph, window, 0);
3689 #ifdef MEMORY_USAGE_STATS
3692 compute_glyph_cachel_usage (glyph_cachel_dynarr *glyph_cachels,
3693 struct overhead_stats *ovstats)
3698 total += Dynarr_memory_usage (glyph_cachels, ovstats);
3703 #endif /* MEMORY_USAGE_STATS */
3707 /*****************************************************************************
3708 * subwindow cachel functions *
3709 *****************************************************************************/
3710 /* subwindows are curious in that you have to physically unmap them to
3711 not display them. It is problematic deciding what to do in
3712 redisplay. We have two caches - a per-window instance cache that
3713 keeps track of subwindows on a window, these are linked to their
3714 instantiator in the hashtable and when the instantiator goes away
3715 we want the instance to go away also. However we also have a
3716 per-frame instance cache that we use to determine if a subwindow is
3717 obscuring an area that we want to clear. We need to be able to flip
3718 through this quickly so a hashtable is not suitable hence the
3719 subwindow_cachels. The question is should we just not mark
3720 instances in the subwindow_cachels or should we try and invalidate
3721 the cache at suitable points in redisplay? If we don't invalidate
3722 the cache it will fill up with crud that will only get removed when
3723 the frame is deleted. So invalidation is good, the question is when
3724 and whether we mark as well. Go for the simple option - don't mark,
3725 MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */
3728 mark_subwindow_cachels (subwindow_cachel_dynarr *elements)
3735 for (elt = 0; elt < Dynarr_length (elements); elt++)
3737 struct subwindow_cachel *cachel = Dynarr_atp (elements, elt);
3738 mark_object (cachel->subwindow);
3743 update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow,
3744 struct subwindow_cachel *cachel)
3746 cachel->subwindow = subwindow;
3747 cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
3748 cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
3749 cachel->updated = 1;
3753 add_subwindow_cachel (struct frame *f, Lisp_Object subwindow)
3755 struct subwindow_cachel new_cachel;
3758 new_cachel.subwindow = Qnil;
3761 new_cachel.being_displayed=0;
3763 update_subwindow_cachel_data (f, subwindow, &new_cachel);
3764 Dynarr_add (f->subwindow_cachels, new_cachel);
3768 get_subwindow_cachel_index (struct frame *f, Lisp_Object subwindow)
3775 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3777 struct subwindow_cachel *cachel =
3778 Dynarr_atp (f->subwindow_cachels, elt);
3780 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
3782 if (!cachel->updated)
3783 update_subwindow_cachel_data (f, subwindow, cachel);
3788 /* If we didn't find the glyph, add it and then return its index. */
3789 add_subwindow_cachel (f, subwindow);
3794 update_subwindow_cachel (Lisp_Object subwindow)
3799 if (NILP (subwindow))
3802 f = XFRAME ( XIMAGE_INSTANCE_SUBWINDOW_FRAME (subwindow));
3804 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3806 struct subwindow_cachel *cachel =
3807 Dynarr_atp (f->subwindow_cachels, elt);
3809 if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
3811 update_subwindow_cachel_data (f, subwindow, cachel);
3816 /* redisplay in general assumes that drawing something will erase
3817 what was there before. unfortunately this does not apply to
3818 subwindows that need to be specifically unmapped in order to
3819 disappear. we take a brute force approach - on the basis that its
3820 cheap - and unmap all subwindows in a display line */
3822 reset_subwindow_cachels (struct frame *f)
3825 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3827 struct subwindow_cachel *cachel =
3828 Dynarr_atp (f->subwindow_cachels, elt);
3830 if (!NILP (cachel->subwindow) && cachel->being_displayed)
3832 cachel->updated = 1;
3833 /* #### This is not optimal as update_subwindow will search
3834 the cachels for ourselves as well. We could easily optimize. */
3835 unmap_subwindow (cachel->subwindow);
3838 Dynarr_reset (f->subwindow_cachels);
3842 mark_subwindow_cachels_as_not_updated (struct frame *f)
3846 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3847 Dynarr_atp (f->subwindow_cachels, elt)->updated = 0;
3852 /*****************************************************************************
3853 * subwindow exposure ignorance *
3854 *****************************************************************************/
3855 /* when we unmap subwindows the associated window system will generate
3856 expose events. This we do not want as redisplay already copes with
3857 the repainting necessary. Worse, we can get in an endless cycle of
3858 redisplay if we are not careful. Thus we keep a per-frame list of
3859 expose events that are going to come and ignore them as
3862 struct expose_ignore_blocktype
3864 Blocktype_declare (struct expose_ignore);
3865 } *the_expose_ignore_blocktype;
3868 check_for_ignored_expose (struct frame* f, int x, int y, int width, int height)
3870 struct expose_ignore *ei, *prev;
3871 /* the ignore list is FIFO so we should generally get a match with
3872 the first element in the list */
3873 for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next)
3875 /* Checking for exact matches just isn't good enough as we
3876 mighte get exposures for partially obscure subwindows, thus
3877 we have to check for overlaps. Being conservative we will
3878 check for exposures wholly contained by the subwindow, this
3879 might give us what we want.*/
3880 if (ei->x <= x && ei->y <= y
3881 && ei->x + ei->width >= x + width
3882 && ei->y + ei->height >= y + height)
3884 #ifdef DEBUG_WIDGETS
3885 stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n",
3886 x, y, width, height, ei->x, ei->y, ei->width, ei->height);
3889 f->subwindow_exposures = ei->next;
3891 prev->next = ei->next;
3893 if (ei == f->subwindow_exposures_tail)
3894 f->subwindow_exposures_tail = prev;
3896 Blocktype_free (the_expose_ignore_blocktype, ei);
3905 register_ignored_expose (struct frame* f, int x, int y, int width, int height)
3907 if (!hold_ignored_expose_registration)
3909 struct expose_ignore *ei;
3911 ei = Blocktype_alloc (the_expose_ignore_blocktype);
3917 ei->height = height;
3919 /* we have to add the exposure to the end of the list, since we
3920 want to check the oldest events first. for speed we keep a record
3921 of the end so that we can add right to it. */
3922 if (f->subwindow_exposures_tail)
3924 f->subwindow_exposures_tail->next = ei;
3926 if (!f->subwindow_exposures)
3928 f->subwindow_exposures = ei;
3930 f->subwindow_exposures_tail = ei;
3934 /****************************************************************************
3935 find_matching_subwindow
3937 See if there is a subwindow that completely encloses the requested
3939 ****************************************************************************/
3940 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height)
3944 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3946 struct subwindow_cachel *cachel =
3947 Dynarr_atp (f->subwindow_cachels, elt);
3949 if (cachel->being_displayed
3951 cachel->x <= x && cachel->y <= y
3953 cachel->x + cachel->width >= x + width
3955 cachel->y + cachel->height >= y + height)
3964 /*****************************************************************************
3965 * subwindow functions *
3966 *****************************************************************************/
3968 /* update the displayed characteristics of a subwindow */
3970 update_subwindow (Lisp_Object subwindow)
3972 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
3974 if (!IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
3976 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
3979 MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
3983 update_frame_subwindows (struct frame *f)
3987 if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed)
3988 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
3990 struct subwindow_cachel *cachel =
3991 Dynarr_atp (f->subwindow_cachels, elt);
3993 if (cachel->being_displayed)
3995 update_subwindow (cachel->subwindow);
4000 /* remove a subwindow from its frame */
4001 void unmap_subwindow (Lisp_Object subwindow)
4003 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4005 struct subwindow_cachel* cachel;
4008 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4010 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
4012 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
4014 #ifdef DEBUG_WIDGETS
4015 stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
4017 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
4018 elt = get_subwindow_cachel_index (f, subwindow);
4019 cachel = Dynarr_atp (f->subwindow_cachels, elt);
4021 /* make sure we don't get expose events */
4022 register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height);
4025 cachel->being_displayed = 0;
4026 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
4028 MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii));
4031 /* show a subwindow in its frame */
4032 void map_subwindow (Lisp_Object subwindow, int x, int y,
4033 struct display_glyph_area *dga)
4035 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
4037 struct subwindow_cachel* cachel;
4040 if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
4042 IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
4044 NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
4047 #ifdef DEBUG_WIDGETS
4048 stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n",
4049 IMAGE_INSTANCE_SUBWINDOW_ID (ii),
4050 dga->width, dga->height, x, y);
4052 f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
4053 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
4054 elt = get_subwindow_cachel_index (f, subwindow);
4055 cachel = Dynarr_atp (f->subwindow_cachels, elt);
4058 cachel->width = dga->width;
4059 cachel->height = dga->height;
4060 cachel->being_displayed = 1;
4062 MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga));
4066 subwindow_possible_dest_types (void)
4068 return IMAGE_SUBWINDOW_MASK;
4071 /* Partially instantiate a subwindow. */
4073 subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
4074 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
4075 int dest_mask, Lisp_Object domain)
4077 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
4078 Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
4079 Lisp_Object frame = FW_FRAME (domain);
4080 Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width);
4081 Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height);
4084 signal_simple_error ("No selected frame", device);
4086 if (!(dest_mask & IMAGE_SUBWINDOW_MASK))
4087 incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK);
4090 IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
4091 IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
4092 IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame;
4094 /* this stuff may get overidden by the widget code */
4096 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20;
4101 if (XINT (width) > 1)
4103 IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w;
4106 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20;
4111 if (XINT (height) > 1)
4113 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h;
4117 DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
4118 Return non-nil if OBJECT is a subwindow.
4122 CHECK_IMAGE_INSTANCE (object);
4123 return (XIMAGE_INSTANCE_TYPE (object) == IMAGE_SUBWINDOW) ? Qt : Qnil;
4126 DEFUN ("image-instance-subwindow-id", Fimage_instance_subwindow_id, 1, 1, 0, /*
4127 Return the window id of SUBWINDOW as a number.
4131 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4132 return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow));
4135 DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
4136 Resize SUBWINDOW to WIDTH x HEIGHT.
4137 If a value is nil that parameter is not changed.
4139 (subwindow, width, height))
4143 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4146 neww = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
4148 neww = XINT (width);
4151 newh = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
4153 newh = XINT (height);
4156 MAYBE_DEVMETH (XDEVICE (XIMAGE_INSTANCE_DEVICE (subwindow)),
4157 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh));
4159 XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh;
4160 XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww;
4162 /* need to update the cachels as redisplay will not do this */
4163 update_subwindow_cachel (subwindow);
4168 DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /*
4169 Generate a Map event for SUBWINDOW.
4173 CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
4175 map_subwindow (subwindow, 0, 0);
4181 /*****************************************************************************
4183 *****************************************************************************/
4185 /* Get the display tables for use currently on window W with face
4186 FACE. #### This will have to be redone. */
4189 get_display_tables (struct window *w, face_index findex,
4190 Lisp_Object *face_table, Lisp_Object *window_table)
4193 tem = WINDOW_FACE_CACHEL_DISPLAY_TABLE (w, findex);
4197 tem = noseeum_cons (tem, Qnil);
4199 tem = w->display_table;
4203 tem = noseeum_cons (tem, Qnil);
4204 *window_table = tem;
4208 display_table_entry (Emchar ch, Lisp_Object face_table,
4209 Lisp_Object window_table)
4213 /* Loop over FACE_TABLE, and then over WINDOW_TABLE. */
4214 for (tail = face_table; 1; tail = XCDR (tail))
4219 if (!NILP (window_table))
4221 tail = window_table;
4222 window_table = Qnil;
4227 table = XCAR (tail);
4229 if (VECTORP (table))
4231 if (ch < XVECTOR_LENGTH (table) && !NILP (XVECTOR_DATA (table)[ch]))
4232 return XVECTOR_DATA (table)[ch];
4236 else if (CHAR_TABLEP (table)
4237 && XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_CHAR)
4239 return get_char_table (ch, XCHAR_TABLE (table));
4241 else if (CHAR_TABLEP (table)
4242 && XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_GENERIC)
4244 Lisp_Object gotit = get_char_table (ch, XCHAR_TABLE (table));
4250 else if (RANGE_TABLEP (table))
4252 Lisp_Object gotit = Fget_range_table (make_char (ch), table, Qnil);
4263 /*****************************************************************************
4264 * timeouts for animated glyphs *
4265 *****************************************************************************/
4266 static Lisp_Object Qglyph_animated_timeout_handler;
4268 DEFUN ("glyph-animated-timeout-handler", Fglyph_animated_timeout_handler, 1, 1, 0, /*
4269 Callback function for updating animated images.
4274 CHECK_WEAK_LIST (arg);
4276 if (!NILP (XWEAK_LIST_LIST (arg)) && !NILP (XCAR (XWEAK_LIST_LIST (arg))))
4278 Lisp_Object value = XCAR (XWEAK_LIST_LIST (arg));
4280 if (IMAGE_INSTANCEP (value))
4282 struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (value);
4284 if (COLOR_PIXMAP_IMAGE_INSTANCEP (value)
4286 IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) > 1
4288 !disable_animated_pixmaps)
4290 /* Increment the index of the image slice we are currently
4292 IMAGE_INSTANCE_PIXMAP_SLICE (ii) =
4293 (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1)
4294 % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii);
4295 /* We might need to kick redisplay at this point - but we
4297 MARK_DEVICE_FRAMES_GLYPHS_CHANGED
4298 (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
4299 IMAGE_INSTANCE_DIRTYP (ii) = 1;
4306 Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object image)
4308 Lisp_Object ret = Qnil;
4310 if (tickms > 0 && IMAGE_INSTANCEP (image))
4312 double ms = ((double)tickms) / 1000.0;
4313 struct gcpro gcpro1;
4314 Lisp_Object holder = make_weak_list (WEAK_LIST_SIMPLE);
4317 XWEAK_LIST_LIST (holder) = Fcons (image, Qnil);
4319 ret = Fadd_timeout (make_float (ms),
4320 Qglyph_animated_timeout_handler,
4321 holder, make_float (ms));
4328 void disable_glyph_animated_timeout (int i)
4333 Fdisable_timeout (id);
4337 /*****************************************************************************
4339 *****************************************************************************/
4342 syms_of_glyphs (void)
4344 /* image instantiators */
4346 DEFSUBR (Fimage_instantiator_format_list);
4347 DEFSUBR (Fvalid_image_instantiator_format_p);
4348 DEFSUBR (Fset_console_type_image_conversion_list);
4349 DEFSUBR (Fconsole_type_image_conversion_list);
4351 defkeyword (&Q_file, ":file");
4352 defkeyword (&Q_data, ":data");
4353 defkeyword (&Q_face, ":face");
4354 defkeyword (&Q_pixel_height, ":pixel-height");
4355 defkeyword (&Q_pixel_width, ":pixel-width");
4358 defkeyword (&Q_color_symbols, ":color-symbols");
4360 #ifdef HAVE_WINDOW_SYSTEM
4361 defkeyword (&Q_mask_file, ":mask-file");
4362 defkeyword (&Q_mask_data, ":mask-data");
4363 defkeyword (&Q_hotspot_x, ":hotspot-x");
4364 defkeyword (&Q_hotspot_y, ":hotspot-y");
4365 defkeyword (&Q_foreground, ":foreground");
4366 defkeyword (&Q_background, ":background");
4368 /* image specifiers */
4370 DEFSUBR (Fimage_specifier_p);
4371 /* Qimage in general.c */
4373 /* image instances */
4375 defsymbol (&Qimage_instancep, "image-instance-p");
4377 defsymbol (&Qnothing_image_instance_p, "nothing-image-instance-p");
4378 defsymbol (&Qtext_image_instance_p, "text-image-instance-p");
4379 defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p");
4380 defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p");
4381 defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p");
4382 defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p");
4383 defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p");
4384 defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p");
4386 DEFSUBR (Fmake_image_instance);
4387 DEFSUBR (Fimage_instance_p);
4388 DEFSUBR (Fimage_instance_type);
4389 DEFSUBR (Fvalid_image_instance_type_p);
4390 DEFSUBR (Fimage_instance_type_list);
4391 DEFSUBR (Fimage_instance_name);
4392 DEFSUBR (Fimage_instance_string);
4393 DEFSUBR (Fimage_instance_file_name);
4394 DEFSUBR (Fimage_instance_mask_file_name);
4395 DEFSUBR (Fimage_instance_depth);
4396 DEFSUBR (Fimage_instance_height);
4397 DEFSUBR (Fimage_instance_width);
4398 DEFSUBR (Fimage_instance_hotspot_x);
4399 DEFSUBR (Fimage_instance_hotspot_y);
4400 DEFSUBR (Fimage_instance_foreground);
4401 DEFSUBR (Fimage_instance_background);
4402 DEFSUBR (Fimage_instance_property);
4403 DEFSUBR (Fset_image_instance_property);
4404 DEFSUBR (Fcolorize_image_instance);
4406 DEFSUBR (Fsubwindowp);
4407 DEFSUBR (Fimage_instance_subwindow_id);
4408 DEFSUBR (Fresize_subwindow);
4409 DEFSUBR (Fforce_subwindow_map);
4411 /* Qnothing defined as part of the "nothing" image-instantiator
4413 /* Qtext defined in general.c */
4414 defsymbol (&Qmono_pixmap, "mono-pixmap");
4415 defsymbol (&Qcolor_pixmap, "color-pixmap");
4416 /* Qpointer defined in general.c */
4420 defsymbol (&Qglyphp, "glyphp");
4421 defsymbol (&Qcontrib_p, "contrib-p");
4422 defsymbol (&Qbaseline, "baseline");
4424 defsymbol (&Qbuffer_glyph_p, "buffer-glyph-p");
4425 defsymbol (&Qpointer_glyph_p, "pointer-glyph-p");
4426 defsymbol (&Qicon_glyph_p, "icon-glyph-p");
4428 defsymbol (&Qconst_glyph_variable, "const-glyph-variable");
4430 DEFSUBR (Fglyph_type);
4431 DEFSUBR (Fvalid_glyph_type_p);
4432 DEFSUBR (Fglyph_type_list);
4434 DEFSUBR (Fmake_glyph_internal);
4435 DEFSUBR (Fglyph_width);
4436 DEFSUBR (Fglyph_ascent);
4437 DEFSUBR (Fglyph_descent);
4438 DEFSUBR (Fglyph_height);
4440 /* Qbuffer defined in general.c. */
4441 /* Qpointer defined above */
4443 /* Unfortunately, timeout handlers must be lisp functions. This is
4444 for animated glyphs. */
4445 defsymbol (&Qglyph_animated_timeout_handler,
4446 "glyph-animated-timeout-handler");
4447 DEFSUBR (Fglyph_animated_timeout_handler);
4450 deferror (&Qimage_conversion_error,
4451 "image-conversion-error",
4452 "image-conversion error", Qio_error);
4456 static const struct lrecord_description image_specifier_description[] = {
4457 { XD_LISP_OBJECT, specifier_data_offset + offsetof(struct image_specifier, attachee), 2 },
4462 specifier_type_create_image (void)
4464 /* image specifiers */
4466 INITIALIZE_SPECIFIER_TYPE_WITH_DATA (image, "image", "imagep");
4468 SPECIFIER_HAS_METHOD (image, create);
4469 SPECIFIER_HAS_METHOD (image, mark);
4470 SPECIFIER_HAS_METHOD (image, instantiate);
4471 SPECIFIER_HAS_METHOD (image, validate);
4472 SPECIFIER_HAS_METHOD (image, after_change);
4473 SPECIFIER_HAS_METHOD (image, going_to_add);
4477 reinit_specifier_type_create_image (void)
4479 REINITIALIZE_SPECIFIER_TYPE (image);
4483 static const struct lrecord_description iike_description_1[] = {
4484 { XD_LISP_OBJECT, offsetof(ii_keyword_entry, keyword), 1 },
4488 static const struct struct_description iike_description = {
4489 sizeof(ii_keyword_entry),
4493 static const struct lrecord_description iiked_description_1[] = {
4494 XD_DYNARR_DESC(ii_keyword_entry_dynarr, &iike_description),
4498 static const struct struct_description iiked_description = {
4499 sizeof(ii_keyword_entry_dynarr),
4503 static const struct lrecord_description iife_description_1[] = {
4504 { XD_LISP_OBJECT, offsetof(image_instantiator_format_entry, symbol), 2 },
4505 { XD_STRUCT_PTR, offsetof(image_instantiator_format_entry, meths), 1, &iim_description },
4509 static const struct struct_description iife_description = {
4510 sizeof(image_instantiator_format_entry),
4514 static const struct lrecord_description iifed_description_1[] = {
4515 XD_DYNARR_DESC(image_instantiator_format_entry_dynarr, &iife_description),
4519 static const struct struct_description iifed_description = {
4520 sizeof(image_instantiator_format_entry_dynarr),
4524 static const struct lrecord_description iim_description_1[] = {
4525 { XD_LISP_OBJECT, offsetof(struct image_instantiator_methods, symbol), 2 },
4526 { XD_STRUCT_PTR, offsetof(struct image_instantiator_methods, keywords), 1, &iiked_description },
4527 { XD_STRUCT_PTR, offsetof(struct image_instantiator_methods, consoles), 1, &cted_description },
4531 const struct struct_description iim_description = {
4532 sizeof(struct image_instantiator_methods),
4537 image_instantiator_format_create (void)
4539 /* image instantiators */
4541 the_image_instantiator_format_entry_dynarr =
4542 Dynarr_new (image_instantiator_format_entry);
4544 Vimage_instantiator_format_list = Qnil;
4545 staticpro (&Vimage_instantiator_format_list);
4547 dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description);
4549 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing");
4551 IIFORMAT_HAS_METHOD (nothing, possible_dest_types);
4552 IIFORMAT_HAS_METHOD (nothing, instantiate);
4554 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (inherit, "inherit");
4556 IIFORMAT_HAS_METHOD (inherit, validate);
4557 IIFORMAT_HAS_METHOD (inherit, normalize);
4558 IIFORMAT_HAS_METHOD (inherit, possible_dest_types);
4559 IIFORMAT_HAS_METHOD (inherit, instantiate);
4561 IIFORMAT_VALID_KEYWORD (inherit, Q_face, check_valid_face);
4563 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (string, "string");
4565 IIFORMAT_HAS_METHOD (string, validate);
4566 IIFORMAT_HAS_METHOD (string, possible_dest_types);
4567 IIFORMAT_HAS_METHOD (string, instantiate);
4569 IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string);
4570 /* Do this so we can set strings. */
4571 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text");
4572 IIFORMAT_HAS_METHOD (text, set_property);
4574 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string");
4576 IIFORMAT_HAS_METHOD (formatted_string, validate);
4577 IIFORMAT_HAS_METHOD (formatted_string, possible_dest_types);
4578 IIFORMAT_HAS_METHOD (formatted_string, instantiate);
4579 IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string);
4582 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow");
4583 IIFORMAT_HAS_METHOD (subwindow, possible_dest_types);
4584 IIFORMAT_HAS_METHOD (subwindow, instantiate);
4585 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int);
4586 IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int);
4588 #ifdef HAVE_WINDOW_SYSTEM
4589 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm");
4591 IIFORMAT_HAS_METHOD (xbm, validate);
4592 IIFORMAT_HAS_METHOD (xbm, normalize);
4593 IIFORMAT_HAS_METHOD (xbm, possible_dest_types);
4595 IIFORMAT_VALID_KEYWORD (xbm, Q_data, check_valid_xbm_inline);
4596 IIFORMAT_VALID_KEYWORD (xbm, Q_file, check_valid_string);
4597 IIFORMAT_VALID_KEYWORD (xbm, Q_mask_data, check_valid_xbm_inline);
4598 IIFORMAT_VALID_KEYWORD (xbm, Q_mask_file, check_valid_string);
4599 IIFORMAT_VALID_KEYWORD (xbm, Q_hotspot_x, check_valid_int);
4600 IIFORMAT_VALID_KEYWORD (xbm, Q_hotspot_y, check_valid_int);
4601 IIFORMAT_VALID_KEYWORD (xbm, Q_foreground, check_valid_string);
4602 IIFORMAT_VALID_KEYWORD (xbm, Q_background, check_valid_string);
4603 #endif /* HAVE_WINDOW_SYSTEM */
4606 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xface, "xface");
4608 IIFORMAT_HAS_METHOD (xface, validate);
4609 IIFORMAT_HAS_METHOD (xface, normalize);
4610 IIFORMAT_HAS_METHOD (xface, possible_dest_types);
4612 IIFORMAT_VALID_KEYWORD (xface, Q_data, check_valid_string);
4613 IIFORMAT_VALID_KEYWORD (xface, Q_file, check_valid_string);
4614 IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_x, check_valid_int);
4615 IIFORMAT_VALID_KEYWORD (xface, Q_hotspot_y, check_valid_int);
4616 IIFORMAT_VALID_KEYWORD (xface, Q_foreground, check_valid_string);
4617 IIFORMAT_VALID_KEYWORD (xface, Q_background, check_valid_string);
4621 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xpm, "xpm");
4623 IIFORMAT_HAS_METHOD (xpm, validate);
4624 IIFORMAT_HAS_METHOD (xpm, normalize);
4625 IIFORMAT_HAS_METHOD (xpm, possible_dest_types);
4627 IIFORMAT_VALID_KEYWORD (xpm, Q_data, check_valid_string);
4628 IIFORMAT_VALID_KEYWORD (xpm, Q_file, check_valid_string);
4629 IIFORMAT_VALID_KEYWORD (xpm, Q_color_symbols, check_valid_xpm_color_symbols);
4630 #endif /* HAVE_XPM */
4634 reinit_vars_of_glyphs (void)
4636 the_expose_ignore_blocktype =
4637 Blocktype_new (struct expose_ignore_blocktype);
4639 hold_ignored_expose_registration = 0;
4644 vars_of_glyphs (void)
4646 reinit_vars_of_glyphs ();
4648 Vthe_nothing_vector = vector1 (Qnothing);
4649 staticpro (&Vthe_nothing_vector);
4651 /* image instances */
4653 Vimage_instance_type_list = Fcons (Qnothing,
4654 list6 (Qtext, Qmono_pixmap, Qcolor_pixmap,
4655 Qpointer, Qsubwindow, Qwidget));
4656 staticpro (&Vimage_instance_type_list);
4660 Vglyph_type_list = list3 (Qbuffer, Qpointer, Qicon);
4661 staticpro (&Vglyph_type_list);
4663 /* The octal-escape glyph, control-arrow-glyph and
4664 invisible-text-glyph are completely initialized in glyphs.el */
4666 DEFVAR_LISP ("octal-escape-glyph", &Voctal_escape_glyph /*
4667 What to prefix character codes displayed in octal with.
4669 Voctal_escape_glyph = allocate_glyph (GLYPH_BUFFER, redisplay_glyph_changed);
4671 DEFVAR_LISP ("control-arrow-glyph", &Vcontrol_arrow_glyph /*
4672 What to use as an arrow for control characters.
4674 Vcontrol_arrow_glyph = allocate_glyph (GLYPH_BUFFER,
4675 redisplay_glyph_changed);
4677 DEFVAR_LISP ("invisible-text-glyph", &Vinvisible_text_glyph /*
4678 What to use to indicate the presence of invisible text.
4679 This is the glyph that is displayed when an ellipsis is called for
4680 \(see `selective-display-ellipses' and `buffer-invisibility-spec').
4681 Normally this is three dots ("...").
4683 Vinvisible_text_glyph = allocate_glyph (GLYPH_BUFFER,
4684 redisplay_glyph_changed);
4686 /* Partially initialized in glyphs.el */
4687 DEFVAR_LISP ("hscroll-glyph", &Vhscroll_glyph /*
4688 What to display at the beginning of horizontally scrolled lines.
4690 Vhscroll_glyph = allocate_glyph (GLYPH_BUFFER, redisplay_glyph_changed);
4691 #ifdef HAVE_WINDOW_SYSTEM
4697 DEFVAR_LISP ("xpm-color-symbols", &Vxpm_color_symbols /*
4698 Definitions of logical color-names used when reading XPM files.
4699 Elements of this list should be of the form (COLOR-NAME FORM-TO-EVALUATE).
4700 The COLOR-NAME should be a string, which is the name of the color to define;
4701 the FORM should evaluate to a `color' specifier object, or a string to be
4702 passed to `make-color-instance'. If a loaded XPM file references a symbolic
4703 color called COLOR-NAME, it will display as the computed color instead.
4705 The default value of this variable defines the logical color names
4706 \"foreground\" and \"background\" to be the colors of the `default' face.
4708 Vxpm_color_symbols = Qnil; /* initialized in x-faces.el */
4709 #endif /* HAVE_XPM */
4714 DEFVAR_BOOL ("disable-animated-pixmaps", &disable_animated_pixmaps /*
4715 Whether animated pixmaps should be animated.
4718 disable_animated_pixmaps = 0;
4722 specifier_vars_of_glyphs (void)
4724 /* #### Can we GC here? The set_specifier_* calls definitely need */
4726 /* display tables */
4728 DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /*
4729 *The display table currently in use.
4730 This is a specifier; use `set-specifier' to change it.
4731 The display table is a vector created with `make-display-table'.
4732 The 256 elements control how to display each possible text character.
4733 Each value should be a string, a glyph, a vector or nil.
4734 If a value is a vector it must be composed only of strings and glyphs.
4735 nil means display the character in the default fashion.
4736 Faces can have their own, overriding display table.
4738 Vcurrent_display_table = Fmake_specifier (Qdisplay_table);
4739 set_specifier_fallback (Vcurrent_display_table,
4740 list1 (Fcons (Qnil, Qnil)));
4741 set_specifier_caching (Vcurrent_display_table,
4742 slot_offset (struct window,
4744 some_window_value_changed,
4749 complex_vars_of_glyphs (void)
4751 /* Partially initialized in glyphs-x.c, glyphs.el */
4752 DEFVAR_LISP ("truncation-glyph", &Vtruncation_glyph /*
4753 What to display at the end of truncated lines.
4755 Vtruncation_glyph = allocate_glyph (GLYPH_BUFFER, redisplay_glyph_changed);
4757 /* Partially initialized in glyphs-x.c, glyphs.el */
4758 DEFVAR_LISP ("continuation-glyph", &Vcontinuation_glyph /*
4759 What to display at the end of wrapped lines.
4761 Vcontinuation_glyph = allocate_glyph (GLYPH_BUFFER, redisplay_glyph_changed);
4763 /* Partially initialized in glyphs-x.c, glyphs.el */
4764 DEFVAR_LISP ("xemacs-logo", &Vxemacs_logo /*
4765 The glyph used to display the XEmacs logo at startup.
4767 Vxemacs_logo = allocate_glyph (GLYPH_BUFFER, 0);