5903f1c8fe14768083fa73e103c12d0d8630d8a2
[chise/xemacs-chise.git.1] / src / glyphs.h
1 /* Generic glyph data structures + display tables
2    Copyright (C) 1994 Board of Trustees, University of Illinois.
3    Copyright (C) 1995, 1996 Ben Wing
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Not in FSF. */
23
24 #ifndef INCLUDED_glyphs_h_
25 #define INCLUDED_glyphs_h_
26
27 #include "specifier.h"
28 #include "gui.h"
29
30 /************************************************************************/
31 /*                      Image Instantiators                             */
32 /************************************************************************/
33
34 struct image_instantiator_methods;
35
36 /* Remember the distinction between image instantiator formats and
37    image instance types.  Here's an approximate mapping:
38
39   image instantiator format     image instance type
40   -------------------------     -------------------
41   nothing                       nothing
42   string                        text
43   formatted-string              text
44   xbm                           mono-pixmap, color-pixmap, pointer
45   xpm                           color-pixmap, mono-pixmap, pointer
46   xface                         mono-pixmap, color-pixmap, pointer
47   gif                           color-pixmap
48   jpeg                          color-pixmap
49   png                           color-pixmap
50   tiff                          color-pixmap
51   bmp                           color-pixmap
52   cursor-font                   pointer
53   mswindows-resource            pointer, color-pixmap
54   font                          pointer
55   subwindow                     subwindow
56   inherit                       mono-pixmap
57   autodetect                    mono-pixmap, color-pixmap, pointer, text
58   button                        widget
59   edit-field                    widget
60   combo-box                     widget
61   progress-gauge                widget
62   tab-control                   widget
63   tree-view                     widget
64   scrollbar                     widget
65   label                         widget
66   layout                        widget
67   native-layout                 widget
68 */
69
70 /* These are methods specific to a particular format of image instantiator
71    (e.g. xpm, string, etc.). */
72
73 typedef struct ii_keyword_entry ii_keyword_entry;
74 struct ii_keyword_entry
75 {
76   Lisp_Object keyword;
77   void (*validate) (Lisp_Object data);
78   int multiple_p;
79   int copy_p;
80 };
81
82 typedef struct
83 {
84   Dynarr_declare (ii_keyword_entry);
85 } ii_keyword_entry_dynarr;
86
87 extern const struct struct_description iim_description;
88
89 enum image_instance_geometry
90 {
91   IMAGE_GEOMETRY,
92   IMAGE_DESIRED_GEOMETRY,
93   IMAGE_MIN_GEOMETRY,
94   IMAGE_MAX_GEOMETRY
95 };
96
97 #define IMAGE_UNSPECIFIED_GEOMETRY -1
98 #define IMAGE_UNCHANGED_GEOMETRY -2
99
100 #define WIDGET_BORDER_HEIGHT 4
101 #define WIDGET_BORDER_WIDTH 4
102
103 enum governing_domain
104 {
105   GOVERNING_DOMAIN_WINDOW,
106   GOVERNING_DOMAIN_FRAME,
107   GOVERNING_DOMAIN_DEVICE
108 };
109
110 struct image_instantiator_methods
111 {
112   Lisp_Object symbol;
113
114   Lisp_Object device;           /* sometimes used */
115
116   ii_keyword_entry_dynarr *keywords;
117   /* consoles this ii is supported on */
118   console_type_entry_dynarr *consoles;
119   /* Implementation specific methods: */
120
121   /* Validate method: Given an instantiator vector, signal an error if
122      it's invalid for this image-instantiator format.  Note that this
123      validation only occurs after all the keyword-specific validation
124      has already been performed.  This is chiefly useful for making
125      sure that certain required keywords are present. */
126   void (*validate_method) (Lisp_Object instantiator);
127
128   /* Normalize method: Given an instantiator, convert it to the form
129      that should be used in a glyph, for devices of type CONSOLE_TYPE.
130      Signal an error if conversion fails. */
131   Lisp_Object (*normalize_method) (Lisp_Object instantiator,
132                                    Lisp_Object console_type,
133                                    Lisp_Object dest_mask);
134
135   /* Governing domain method: Return an int indicating what type of
136      domain an instance in this format is governed by. */
137   int (*governing_domain_method) (void);
138
139   /* Possible-dest-types method: Return a mask indicating what dest types
140      are compatible with this format. */
141   int (*possible_dest_types_method) (void);
142
143   /* Instantiate method: Given an instantiator and a partially
144      filled-in image instance, complete the filling-in.  Return
145      non-zero if the instantiation succeeds, 0 if it fails.
146      This must be present. */
147   void (*instantiate_method) (Lisp_Object image_instance,
148                               Lisp_Object instantiator,
149                               Lisp_Object pointer_fg,
150                               Lisp_Object pointer_bg,
151                               int dest_mask,
152                               Lisp_Object domain);
153   /* Post instantiate method: finish instantiation of the image
154      instance. */
155   void (*post_instantiate_method) (Lisp_Object image_instance,
156                                    Lisp_Object instantiator,
157                                    Lisp_Object domain);
158   /* Property method: Given an image instance, return device specific
159      properties. */
160   Lisp_Object (*property_method) (Lisp_Object image_instance,
161                                   Lisp_Object property);
162   /* Set-property method: Given an image instance, set device specific
163      properties. */
164   Lisp_Object (*set_property_method) (Lisp_Object image_instance,
165                                       Lisp_Object property,
166                                       Lisp_Object val);
167   /* Asynchronously update properties. */
168   void (*update_method) (Lisp_Object image_instance,
169                          Lisp_Object instantiator);
170   void (*redisplay_method) (Lisp_Object image_instance);
171
172   /* Find out the desired geometry, as given by disp, of this image
173    instance. Actual geometry is stored in the appropriate slots in the
174    image instance. */
175   void (*query_geometry_method) (Lisp_Object image_instance,
176                                  int* width, int* height,
177                                  enum image_instance_geometry disp,
178                                  Lisp_Object domain);
179
180   /* Layout the instance and its children bounded by the provided
181      dimensions. Returns success or failure. */
182   int (*layout_method) (Lisp_Object image_instance,
183                         int width, int height, int xoffset, int yoffset,
184                         Lisp_Object domain);
185 };
186
187 /***** Calling an image-instantiator method *****/
188
189 #define HAS_IIFORMAT_METH_P(mstruc, m) (((mstruc)->m##_method) != 0)
190 #define IIFORMAT_METH(mstruc, m, args) (((mstruc)->m##_method) args)
191
192 /* Call a void-returning specifier method, if it exists */
193 #define MAYBE_IIFORMAT_METH(mstruc, m, args)                    \
194 do {                                                            \
195   struct image_instantiator_methods *MIM_mstruc = (mstruc);     \
196   if (MIM_mstruc && HAS_IIFORMAT_METH_P (MIM_mstruc, m))        \
197     IIFORMAT_METH (MIM_mstruc, m, args);                        \
198 } while (0)
199
200 #define MAYBE_IIFORMAT_DEVMETH(device, mstruc, m, args) \
201 do {                                                    \
202   struct image_instantiator_methods *MID_mstruc =       \
203     decode_ii_device (device, mstruc);                  \
204   if (MID_mstruc)                                       \
205     MAYBE_IIFORMAT_METH(MID_mstruc, m, args);           \
206 } while (0)
207
208
209 /* Call a specifier method, if it exists; otherwise return
210    the specified value */
211
212 #define IIFORMAT_METH_OR_GIVEN(mstruc, m, args, given)  \
213   ((mstruc && HAS_IIFORMAT_METH_P (mstruc, m)) ?                \
214    IIFORMAT_METH (mstruc, m, args) : (given))
215
216 /***** Defining new image-instantiator types *****/
217
218 #define DECLARE_IMAGE_INSTANTIATOR_FORMAT(format)               \
219 extern struct image_instantiator_methods *format##_image_instantiator_methods
220
221 #define DEFINE_IMAGE_INSTANTIATOR_FORMAT(format)                \
222 struct image_instantiator_methods *format##_image_instantiator_methods
223
224 #define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name)   \
225 do {                                                                    \
226   format##_image_instantiator_methods =                                 \
227     xnew_and_zero (struct image_instantiator_methods);                  \
228   format##_image_instantiator_methods->symbol = Q##format;              \
229   format##_image_instantiator_methods->device = Qnil;                   \
230   format##_image_instantiator_methods->keywords =                       \
231     Dynarr_new (ii_keyword_entry);                                      \
232   format##_image_instantiator_methods->consoles =                       \
233     Dynarr_new (console_type_entry);                                    \
234   add_entry_to_image_instantiator_format_list                           \
235     (Q##format, format##_image_instantiator_methods);                   \
236   dump_add_root_struct_ptr (&format##_image_instantiator_methods,       \
237                             &iim_description);                          \
238 } while (0)
239
240 #define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(format, obj_name)  \
241 do {                                                            \
242   defsymbol (&Q##format, obj_name);                             \
243   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name);\
244 } while (0)
245
246 /* Declare that image-instantiator format FORMAT has method M; used in
247    initialization routines */
248 #define IIFORMAT_HAS_METHOD(format, m) \
249   (format##_image_instantiator_methods->m##_method = format##_##m)
250
251 #define IIFORMAT_HAS_SHARED_METHOD(format, m, type) \
252   (format##_image_instantiator_methods->m##_method = type##_##m)
253
254 /* Declare that KEYW is a valid keyword for image-instantiator format
255    FORMAT.  VALIDATE_FUN if a function that returns whether the data
256    is valid.  The keyword may not appear more than once. */
257 #define IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, copy, multi) \
258   do {                                                          \
259     struct ii_keyword_entry entry;                              \
260                                                                 \
261     entry.keyword = keyw;                                       \
262     entry.validate = validate_fun;                              \
263     entry.multiple_p = multi;                                   \
264     entry.copy_p = copy;                                        \
265     Dynarr_add (format##_image_instantiator_methods->keywords,  \
266                 entry);                                         \
267   } while (0)
268
269 #define IIFORMAT_VALID_KEYWORD(format, keyw, validate_fun)      \
270 IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 1, 0)
271
272 /* Same as IIFORMAT_VALID_KEYWORD except that the keyword may
273    appear multiple times. */
274 #define IIFORMAT_VALID_MULTI_KEYWORD(format, keyw, validate_fun)        \
275 IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 1, 1)
276
277 /* Same as IIFORMAT_VALID_KEYWORD except that the argument is not
278    copied by the specifier functions. This is necessary for things
279    like callbacks etc. */
280 #define IIFORMAT_VALID_NONCOPY_KEYWORD(format, keyw, validate_fun)      \
281 IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 0, 0)
282
283 /* Declare that image-instantiator format FORMAT is supported on
284    CONSOLE type. */
285 #define IIFORMAT_VALID_CONSOLE(console, format)                 \
286   do {                                                          \
287     struct console_type_entry entry;                            \
288                                                                 \
289     entry.symbol = Q##console;                                  \
290     entry.meths = console##_console_methods;                    \
291     Dynarr_add (format##_image_instantiator_methods->consoles,  \
292                 entry);                                         \
293   } while (0)
294
295 #define IIFORMAT_VALID_CONSOLE2(con1, con2, format)             \
296   IIFORMAT_VALID_CONSOLE (con1, format);                        \
297   IIFORMAT_VALID_CONSOLE (con2, format);
298
299 #define DEFINE_DEVICE_IIFORMAT(type, format)    \
300 DECLARE_IMAGE_INSTANTIATOR_FORMAT(format);      \
301 struct image_instantiator_methods *type##_##format##_image_instantiator_methods
302
303 #define INITIALIZE_DEVICE_IIFORMAT(type, format)                                \
304 do {                                                                            \
305   type##_##format##_image_instantiator_methods =                                \
306     xnew_and_zero (struct image_instantiator_methods);                          \
307   type##_##format##_image_instantiator_methods->symbol = Q##format;             \
308   type##_##format##_image_instantiator_methods->device = Q##type;               \
309   type##_##format##_image_instantiator_methods->keywords =                      \
310     Dynarr_new (ii_keyword_entry);                                              \
311   add_entry_to_device_ii_format_list                                            \
312     (Q##type, Q##format, type##_##format##_image_instantiator_methods);         \
313   IIFORMAT_VALID_CONSOLE(type,format);                                          \
314   dump_add_root_struct_ptr (&type##_##format##_image_instantiator_methods,      \
315                             &iim_description);                                  \
316 } while (0)
317
318 /* Declare that image-instantiator format FORMAT has method M; used in
319    initialization routines */
320 #define IIFORMAT_HAS_DEVMETHOD(type, format, m) \
321   (type##_##format##_image_instantiator_methods->m##_method = type##_##format##_##m)
322 #define IIFORMAT_HAS_SHARED_DEVMETHOD(type, format, m, fromformat) \
323   (type##_##format##_image_instantiator_methods->m##_method = type##_##fromformat##_##m)
324
325 #define IIFORMAT_INHERITS_DEVMETHOD(type, from, format, m) \
326   (type##_##format##_image_instantiator_methods->m##_method = from##_##format##_##m)
327 #define IIFORMAT_INHERITS_SHARED_DEVMETHOD(type, from, format, m, fromformat) \
328   (type##_##format##_image_instantiator_methods->m##_method = from##_##fromformat##_##m)
329
330 #define INSTANTIATOR_TYPE(inst) (XVECTOR_DATA ((inst))[0])
331
332 struct image_instantiator_methods *
333 decode_device_ii_format (Lisp_Object device, Lisp_Object format,
334                          Error_behavior errb);
335 struct image_instantiator_methods *
336 decode_image_instantiator_format (Lisp_Object format, Error_behavior errb);
337
338 void add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
339                         struct image_instantiator_methods *meths);
340 void add_entry_to_device_ii_format_list (Lisp_Object device, Lisp_Object symbol,
341                         struct image_instantiator_methods *meths);
342 Lisp_Object find_keyword_in_vector (Lisp_Object vector,
343                                     Lisp_Object keyword);
344 Lisp_Object find_keyword_in_vector_or_given (Lisp_Object vector,
345                                              Lisp_Object keyword,
346                                              Lisp_Object default_);
347 Lisp_Object simple_image_type_normalize (Lisp_Object inst,
348                                          Lisp_Object console_type,
349                                          Lisp_Object image_type_tag);
350 Lisp_Object potential_pixmap_file_instantiator (Lisp_Object instantiator,
351                                                 Lisp_Object file_keyword,
352                                                 Lisp_Object data_keyword,
353                                                 Lisp_Object console_type);
354 void check_valid_string (Lisp_Object data);
355 void check_valid_int (Lisp_Object data);
356 void check_valid_face (Lisp_Object data);
357 void check_valid_vector (Lisp_Object data);
358 void check_valid_item_list (Lisp_Object items);
359
360 void initialize_subwindow_image_instance (Lisp_Image_Instance*);
361 void subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
362                             Lisp_Object pointer_fg, Lisp_Object pointer_bg,
363                             int dest_mask, Lisp_Object domain);
364 int subwindow_governing_domain (void);
365 void widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
366                          Lisp_Object pointer_fg, Lisp_Object pointer_bg,
367                          int dest_mask, Lisp_Object domain);
368 void image_instance_query_geometry (Lisp_Object image_instance,
369                                     int* width, int* height,
370                                     enum image_instance_geometry disp,
371                                     Lisp_Object domain);
372 void image_instance_layout (Lisp_Object image_instance,
373                             int width, int height, int xoffset, int yoffset,
374                             Lisp_Object domain);
375 int layout_layout (Lisp_Object image_instance,
376                    int width, int height, int xoffset, int yoffset,
377                    Lisp_Object domain);
378 int invalidate_glyph_geometry_maybe (Lisp_Object glyph_or_ii, struct window* w);
379 Lisp_Object make_image_instance_cache_hash_table (void);
380
381 DECLARE_DOESNT_RETURN (incompatible_image_types (Lisp_Object instantiator,
382                                                  int given_dest_mask,
383                                                  int desired_dest_mask));
384 DECLARE_DOESNT_RETURN (signal_image_error (const char *, Lisp_Object));
385 DECLARE_DOESNT_RETURN (signal_image_error_2 (const char *, Lisp_Object, Lisp_Object));
386
387 /************************************************************************/
388 /*                      Image Specifier Object                          */
389 /************************************************************************/
390
391 DECLARE_SPECIFIER_TYPE (image);
392 #define XIMAGE_SPECIFIER(x) XSPECIFIER_TYPE (x, image)
393 #define XSETIMAGE_SPECIFIER(x, p) XSETSPECIFIER_TYPE (x, p, image)
394 #define IMAGE_SPECIFIERP(x) SPECIFIER_TYPEP (x, image)
395 #define CHECK_IMAGE_SPECIFIER(x) CHECK_SPECIFIER_TYPE (x, image)
396 #define CONCHECK_IMAGE_SPECIFIER(x) CONCHECK_SPECIFIER_TYPE (x, image)
397
398 void set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph,
399                             Lisp_Object property);
400
401 struct image_specifier
402 {
403   int allowed;
404   Lisp_Object attachee;         /* face or glyph this is attached to, or nil */
405   Lisp_Object attachee_property;/* property of that face or glyph */
406 };
407
408 #define IMAGE_SPECIFIER_DATA(g) SPECIFIER_TYPE_DATA (g, image)
409 #define IMAGE_SPECIFIER_ALLOWED(g) (IMAGE_SPECIFIER_DATA (g)->allowed)
410 #define IMAGE_SPECIFIER_ATTACHEE(g) (IMAGE_SPECIFIER_DATA (g)->attachee)
411 #define IMAGE_SPECIFIER_ATTACHEE_PROPERTY(g) \
412   (IMAGE_SPECIFIER_DATA (g)->attachee_property)
413
414 #define XIMAGE_SPECIFIER_ALLOWED(g) \
415   IMAGE_SPECIFIER_ALLOWED (XIMAGE_SPECIFIER (g))
416
417 /************************************************************************/
418 /*                      Image Instance Object                           */
419 /************************************************************************/
420
421 DECLARE_LRECORD (image_instance, Lisp_Image_Instance);
422 #define XIMAGE_INSTANCE(x) XRECORD (x, image_instance, Lisp_Image_Instance)
423 #define XSETIMAGE_INSTANCE(x, p) XSETRECORD (x, p, image_instance)
424 #define IMAGE_INSTANCEP(x) RECORDP (x, image_instance)
425 #define CHECK_IMAGE_INSTANCE(x) CHECK_RECORD (x, image_instance)
426 #define CONCHECK_IMAGE_INSTANCE(x) CONCHECK_RECORD (x, image_instance)
427
428 #ifdef ERROR_CHECK_GLYPHS
429 void check_image_instance_structure (Lisp_Object instance);
430 void check_window_subwindow_cache (struct window* w);
431 #define ERROR_CHECK_IMAGE_INSTANCE(ii) \
432   check_image_instance_structure (ii)
433 #define ERROR_CHECK_SUBWINDOW_CACHE(w) \
434   check_window_subwindow_cache (w)
435 #else
436 #define ERROR_CHECK_IMAGE_INSTANCE(ii)
437 #define ERROR_CHECK_SUBWINDOW_CACHE(w)
438 #endif
439
440 enum image_instance_type
441 {
442   IMAGE_UNKNOWN,
443   IMAGE_NOTHING,
444   IMAGE_TEXT,
445   IMAGE_MONO_PIXMAP,
446   IMAGE_COLOR_PIXMAP,
447   IMAGE_POINTER,
448   IMAGE_SUBWINDOW,
449   IMAGE_WIDGET
450 };
451
452 #define IMAGE_NOTHING_MASK (1 << 0)
453 #define IMAGE_TEXT_MASK (1 << 1)
454 #define IMAGE_MONO_PIXMAP_MASK (1 << 2)
455 #define IMAGE_COLOR_PIXMAP_MASK (1 << 3)
456 #define IMAGE_POINTER_MASK (1 << 4)
457 #define IMAGE_SUBWINDOW_MASK (1 << 5)
458 #define IMAGE_WIDGET_MASK (1 << 6)
459
460 /* This depends on the fact that enums are assigned consecutive
461    integers starting at 0. (Remember that IMAGE_UNKNOWN is the
462    first enum.) I'm fairly sure this behavior is ANSI-mandated,
463    so there should be no portability problems here. */
464 #define image_instance_type_to_mask(type) \
465   ((int) (1 << ((int) (type) - 1)))
466
467 #define IMAGE_INSTANCE_TYPE_P(ii, type) \
468 (IMAGE_INSTANCEP (ii) && XIMAGE_INSTANCE_TYPE (ii) == type)
469
470 #define NOTHING_IMAGE_INSTANCEP(ii) \
471      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_NOTHING)
472 #define TEXT_IMAGE_INSTANCEP(ii) \
473      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_TEXT)
474 #define MONO_PIXMAP_IMAGE_INSTANCEP(ii) \
475      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_MONO_PIXMAP)
476 #define COLOR_PIXMAP_IMAGE_INSTANCEP(ii) \
477      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_COLOR_PIXMAP)
478 #define POINTER_IMAGE_INSTANCEP(ii) \
479      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_POINTER)
480 #define SUBWINDOW_IMAGE_INSTANCEP(ii) \
481      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_SUBWINDOW)
482 #define WIDGET_IMAGE_INSTANCEP(ii) \
483      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_WIDGET)
484
485 #define CHECK_NOTHING_IMAGE_INSTANCE(x) do {                    \
486   CHECK_IMAGE_INSTANCE (x);                                     \
487   if (!NOTHING_IMAGE_INSTANCEP (x))                             \
488     x = wrong_type_argument (Qnothing_image_instance_p, (x));   \
489 } while (0)
490
491 #define CHECK_TEXT_IMAGE_INSTANCE(x) do {                       \
492   CHECK_IMAGE_INSTANCE (x);                                     \
493   if (!TEXT_IMAGE_INSTANCEP (x))                                \
494     x = wrong_type_argument (Qtext_image_instance_p, (x));      \
495 } while (0)
496
497 #define CHECK_MONO_PIXMAP_IMAGE_INSTANCE(x) do {                        \
498   CHECK_IMAGE_INSTANCE (x);                                             \
499   if (!MONO_PIXMAP_IMAGE_INSTANCEP (x))                                 \
500     x = wrong_type_argument (Qmono_pixmap_image_instance_p, (x));       \
501 } while (0)
502
503 #define CHECK_COLOR_PIXMAP_IMAGE_INSTANCE(x) do {                       \
504   CHECK_IMAGE_INSTANCE (x);                                             \
505   if (!COLOR_PIXMAP_IMAGE_INSTANCEP (x))                                \
506     x = wrong_type_argument (Qcolor_pixmap_image_instance_p, (x));      \
507 } while (0)
508
509 #define CHECK_POINTER_IMAGE_INSTANCE(x) do {                    \
510   CHECK_IMAGE_INSTANCE (x);                                     \
511   if (!POINTER_IMAGE_INSTANCEP (x))                             \
512     x = wrong_type_argument (Qpointer_image_instance_p, (x));   \
513 } while (0)
514
515 #define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do {                  \
516   CHECK_IMAGE_INSTANCE (x);                                     \
517   if (!SUBWINDOW_IMAGE_INSTANCEP (x)                            \
518       && !WIDGET_IMAGE_INSTANCEP (x))                           \
519     x = wrong_type_argument (Qsubwindow_image_instance_p, (x)); \
520 } while (0)
521
522 #define CHECK_WIDGET_IMAGE_INSTANCE(x) do {                     \
523   CHECK_IMAGE_INSTANCE (x);                                     \
524   if (!WIDGET_IMAGE_INSTANCEP (x))                              \
525     x = wrong_type_argument (Qwidget_image_instance_p, (x));    \
526 } while (0)
527
528 struct Lisp_Image_Instance
529 {
530   struct lcrecord_header header;
531   Lisp_Object domain;           /* The domain in which we were cached. */
532   Lisp_Object device;           /* The device of the domain. Recorded
533                                    since the domain may get deleted
534                                    before us. */
535   Lisp_Object name;
536   /* The glyph from which we were instantiated. This is a weak
537      reference. */
538   Lisp_Object parent;
539   /* The instantiator from which we were instantiated. */
540   Lisp_Object instantiator;
541   enum image_instance_type type;
542   unsigned int x_offset, y_offset;      /* for layout purposes */
543   int width, height, margin_width;
544   unsigned long display_hash; /* Hash value representing the structure
545                                  of the image_instance when it was
546                                  last displayed. */
547   unsigned int dirty : 1;
548   unsigned int size_changed : 1;
549   unsigned int text_changed : 1;
550   unsigned int layout_changed : 1;
551   unsigned int optimize_output : 1; /* For outputting layouts. */
552   unsigned int initialized : 1; /* When we're fully done. */
553   unsigned int wants_initial_focus : 1;
554
555   union
556   {
557     struct
558     {
559       unsigned int descent;
560       Lisp_Object string;
561     } text;
562     struct
563     {
564       unsigned int depth;
565       unsigned int slice, maxslice, timeout;
566       Lisp_Object hotspot_x, hotspot_y; /* integer or Qnil */
567       Lisp_Object filename;      /* string or Qnil */
568       Lisp_Object mask_filename; /* string or Qnil */
569       Lisp_Object fg, bg; /* foreground and background colors,
570                              if this is a colorized mono-pixmap
571                              or a pointer */
572       Lisp_Object auxdata;    /* list or Qnil: any additional data
573                                  to be seen from lisp */
574       void* mask;               /* mask that can be seen from all windowing systems */
575     } pixmap; /* used for pointers as well */
576     struct
577     {
578       void* subwindow;          /* specific devices can use this as necessary */
579       struct
580       {                         /* We need these so we can do without
581                                    subwindow_cachel */
582         unsigned int x, y;
583         unsigned int width, height;
584       } display_data;
585       unsigned int being_displayed : 1; /* used to detect when needs
586                                            to be unmapped */
587       unsigned int v_resize : 1;        /* Whether the vsize is allowed to change. */
588       unsigned int h_resize : 1;        /* Whether the hsize is allowed to change. */
589       unsigned int orientation : 1; /* Vertical or horizontal. */
590       unsigned int justification : 2; /* Left, right or center. */
591       /* Face for colors and font. We specify this here because we
592          want people to be able to put :face in the instantiator
593          spec. Using glyph-face is more inconvenient, although more
594          general. */
595       Lisp_Object face;
596       Lisp_Object type;
597       Lisp_Object props;        /* properties or border*/
598       Lisp_Object items;        /* a list of displayed gui_items */
599       Lisp_Object pending_items; /* gui_items that should be displayed */
600       Lisp_Object children;     /* a list of children */
601       Lisp_Object width;        /* dynamic width spec. */
602       Lisp_Object height;       /* dynamic height spec. */
603       /* Change flags to augment dirty. */
604       unsigned int face_changed : 1;
605       unsigned int items_changed : 1;
606       unsigned int action_occurred : 1;
607     } subwindow;
608   } u;
609
610   /* console-type- and image-type-specific data */
611   void *data;
612 };
613
614 /* Layout bit-fields. */
615 #define LAYOUT_HORIZONTAL       0
616 #define LAYOUT_VERTICAL 1
617
618 #define LAYOUT_JUSTIFY_LEFT 0
619 #define LAYOUT_JUSTIFY_RIGHT 1
620 #define LAYOUT_JUSTIFY_CENTER 2
621
622 #define IMAGE_INSTANCE_HASH_DEPTH 0
623
624 /* Accessor macros. */
625 #define IMAGE_INSTANCE_DOMAIN(i) ((i)->domain)
626 #define IMAGE_INSTANCE_DOMAIN_LIVE_P(i) (DOMAIN_LIVE_P ((i)->domain))
627 #define IMAGE_INSTANCE_DEVICE(i) ((i)->device)
628 #define IMAGE_INSTANCE_FRAME(i) (DOMAIN_FRAME ((i)->domain))
629 #define IMAGE_INSTANCE_NAME(i) ((i)->name)
630 #define IMAGE_INSTANCE_PARENT(i) ((i)->parent)
631 #define IMAGE_INSTANCE_INSTANTIATOR(i) ((i)->instantiator)
632 #define IMAGE_INSTANCE_GLYPH(i) (image_instance_parent_glyph(i))
633 #define IMAGE_INSTANCE_TYPE(i) ((i)->type)
634 #define IMAGE_INSTANCE_XOFFSET(i) ((i)->x_offset)
635 #define IMAGE_INSTANCE_YOFFSET(i) ((i)->y_offset)
636 #define IMAGE_INSTANCE_WIDTH(i) ((i)->width)
637 #define IMAGE_INSTANCE_MARGIN_WIDTH(i) ((i)->margin_width)
638 #define IMAGE_INSTANCE_HEIGHT(i) ((i)->height)
639 #define IMAGE_INSTANCE_INITIALIZED(i) ((i)->initialized)
640 #define IMAGE_INSTANCE_DISPLAY_HASH(i) ((i)->display_hash)
641 #define IMAGE_INSTANCE_PIXMAP_TYPE_P(i)                 \
642  ((IMAGE_INSTANCE_TYPE (i) == IMAGE_MONO_PIXMAP)        \
643   || (IMAGE_INSTANCE_TYPE (i) == IMAGE_COLOR_PIXMAP))
644 #define IMAGE_INSTANCE_DIRTYP(i) ((i)->dirty)
645 #define IMAGE_INSTANCE_NEEDS_LAYOUT(i) \
646   ((IMAGE_INSTANCE_DIRTYP (i) && IMAGE_INSTANCE_LAYOUT_CHANGED (i)) \
647    || (FRAMEP (IMAGE_INSTANCE_FRAME (i)) \
648        && XFRAME (IMAGE_INSTANCE_FRAME (i))->size_changed))
649 #define IMAGE_INSTANCE_FACE(i) \
650   (GLYPHP (IMAGE_INSTANCE_GLYPH (i)) ? \
651    XGLYPH_FACE (IMAGE_INSTANCE_GLYPH (i)) : Qnil)
652 #define IMAGE_INSTANCE_WANTS_INITIAL_FOCUS(i) ((i)->wants_initial_focus)
653
654 /* Changed flags */
655 #define IMAGE_INSTANCE_TEXT_CHANGED(i) ((i)->text_changed)
656 #define IMAGE_INSTANCE_SIZE_CHANGED(i) ((i)->size_changed)
657 #define IMAGE_INSTANCE_WIDGET_FACE_CHANGED(i) \
658   ((i)->u.subwindow.face_changed)
659 #define IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED(i) \
660   ((i)->u.subwindow.items_changed)
661 #define IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED(i) \
662   ((i)->u.subwindow.action_occurred)
663 #define IMAGE_INSTANCE_LAYOUT_CHANGED(i) ((i)->layout_changed)
664 #define IMAGE_INSTANCE_OPTIMIZE_OUTPUT(i) ((i)->optimize_output)
665
666 /* Text properties */
667 #define IMAGE_INSTANCE_TEXT_STRING(i) ((i)->u.text.string)
668 #define IMAGE_INSTANCE_TEXT_WIDTH(i) \
669   IMAGE_INSTANCE_WIDTH(i)
670 #define IMAGE_INSTANCE_TEXT_HEIGHT(i) \
671   IMAGE_INSTANCE_HEIGHT(i)
672 #define IMAGE_INSTANCE_TEXT_DESCENT(i) ((i)->u.text.descent)
673 #define IMAGE_INSTANCE_TEXT_ASCENT(i) \
674   (IMAGE_INSTANCE_TEXT_HEIGHT(i) - IMAGE_INSTANCE_TEXT_DESCENT(i))
675
676 /* Pixmap properties */
677 #define IMAGE_INSTANCE_PIXMAP_WIDTH(i) \
678   IMAGE_INSTANCE_WIDTH(i)
679 #define IMAGE_INSTANCE_PIXMAP_HEIGHT(i) \
680   IMAGE_INSTANCE_HEIGHT(i)
681 #define IMAGE_INSTANCE_PIXMAP_DEPTH(i) ((i)->u.pixmap.depth)
682 #define IMAGE_INSTANCE_PIXMAP_FILENAME(i) ((i)->u.pixmap.filename)
683 #define IMAGE_INSTANCE_PIXMAP_MASK_FILENAME(i) ((i)->u.pixmap.mask_filename)
684 #define IMAGE_INSTANCE_PIXMAP_HOTSPOT_X(i) ((i)->u.pixmap.hotspot_x)
685 #define IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y(i) ((i)->u.pixmap.hotspot_y)
686 #define IMAGE_INSTANCE_PIXMAP_FG(i) ((i)->u.pixmap.fg)
687 #define IMAGE_INSTANCE_PIXMAP_BG(i) ((i)->u.pixmap.bg)
688 #define IMAGE_INSTANCE_PIXMAP_AUXDATA(i) ((i)->u.pixmap.auxdata)
689 #define IMAGE_INSTANCE_PIXMAP_MASK(i) ((i)->u.pixmap.mask)
690 #define IMAGE_INSTANCE_PIXMAP_SLICE(i) ((i)->u.pixmap.slice)
691 #define IMAGE_INSTANCE_PIXMAP_MAXSLICE(i) ((i)->u.pixmap.maxslice)
692 #define IMAGE_INSTANCE_PIXMAP_TIMEOUT(i) ((i)->u.pixmap.timeout)
693
694 /* Subwindow properties */
695 #define IMAGE_INSTANCE_SUBWINDOW_ID(i) ((i)->u.subwindow.subwindow)
696 /* Display data. */
697 #define IMAGE_INSTANCE_DISPLAY_X(i) ((i)->u.subwindow.display_data.x)
698 #define IMAGE_INSTANCE_DISPLAY_Y(i) ((i)->u.subwindow.display_data.y)
699 #define IMAGE_INSTANCE_DISPLAY_WIDTH(i) \
700   ((i)->u.subwindow.display_data.width)
701 #define IMAGE_INSTANCE_DISPLAY_HEIGHT(i) \
702   ((i)->u.subwindow.display_data.height)
703 #define IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
704 ((i)->u.subwindow.being_displayed)
705 #define IMAGE_INSTANCE_SUBWINDOW_V_RESIZEP(i) \
706 ((i)->u.subwindow.v_resize)
707 #define IMAGE_INSTANCE_SUBWINDOW_H_RESIZEP(i) \
708 ((i)->u.subwindow.h_resize)
709 #define IMAGE_INSTANCE_SUBWINDOW_ORIENT(i) \
710 ((i)->u.subwindow.orientation)
711 #define IMAGE_INSTANCE_SUBWINDOW_JUSTIFY(i) \
712 ((i)->u.subwindow.justification)
713 #define IMAGE_INSTANCE_SUBWINDOW_FACE(i) \
714 ((i)->u.subwindow.face)
715
716 /* Widget properties */
717 #define IMAGE_INSTANCE_WIDGET_WIDTH(i) \
718   IMAGE_INSTANCE_WIDTH(i)
719 #define IMAGE_INSTANCE_WIDGET_HEIGHT(i) \
720   IMAGE_INSTANCE_HEIGHT(i)
721 #define IMAGE_INSTANCE_WIDGET_WIDTH_SUBR(i) ((i)->u.subwindow.width)
722 #define IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR(i) ((i)->u.subwindow.height)
723 #define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.type)
724 #define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.props)
725 #define SET_IMAGE_INSTANCE_WIDGET_FACE(i,f) \
726  ((i)->u.subwindow.face = f)
727 #define IMAGE_INSTANCE_WIDGET_FACE(i)                           \
728   (!NILP ((i)->u.subwindow.face) ? (i)->u.subwindow.face :      \
729   !NILP (IMAGE_INSTANCE_FACE (i)) ? IMAGE_INSTANCE_FACE (i) :   \
730   Vwidget_face)
731 #define IMAGE_INSTANCE_WIDGET_ITEMS(i) ((i)->u.subwindow.items)
732 #define IMAGE_INSTANCE_WIDGET_PENDING_ITEMS(i) \
733   ((i)->u.subwindow.pending_items)
734 #define IMAGE_INSTANCE_WIDGET_ITEM(i)           \
735   (CONSP (IMAGE_INSTANCE_WIDGET_ITEMS (i)) ?    \
736    XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (i)) :     \
737    IMAGE_INSTANCE_WIDGET_ITEMS (i))
738 #define IMAGE_INSTANCE_WIDGET_TEXT(i) \
739    XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (i))->name
740
741 /* Layout properties */
742 #define IMAGE_INSTANCE_LAYOUT_CHILDREN(i) ((i)->u.subwindow.children)
743 #define IMAGE_INSTANCE_LAYOUT_BORDER(i) ((i)->u.subwindow.props)
744
745 #define XIMAGE_INSTANCE_DOMAIN(i) \
746   IMAGE_INSTANCE_DOMAIN (XIMAGE_INSTANCE (i))
747 #define XIMAGE_INSTANCE_DOMAIN_LIVE_P(i) \
748   IMAGE_INSTANCE_DOMAIN_LIVE_P (XIMAGE_INSTANCE (i))
749 #define XIMAGE_INSTANCE_DEVICE(i) \
750   IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (i))
751 #define XIMAGE_INSTANCE_FRAME(i) \
752   IMAGE_INSTANCE_FRAME (XIMAGE_INSTANCE (i))
753 #define XIMAGE_INSTANCE_NAME(i) \
754   IMAGE_INSTANCE_NAME (XIMAGE_INSTANCE (i))
755 #define XIMAGE_INSTANCE_GLYPH(i) \
756   IMAGE_INSTANCE_GLYPH (XIMAGE_INSTANCE (i))
757 #define XIMAGE_INSTANCE_PARENT(i) \
758   IMAGE_INSTANCE_PARENT (XIMAGE_INSTANCE (i))
759 #define XIMAGE_INSTANCE_INSTANTIATOR(i) \
760   IMAGE_INSTANCE_INSTANTIATOR (XIMAGE_INSTANCE (i))
761 #define XIMAGE_INSTANCE_TYPE(i) \
762   IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (i))
763 #define XIMAGE_INSTANCE_DISPLAY_HASH(i) \
764   IMAGE_INSTANCE_DISPLAY_HASH (XIMAGE_INSTANCE (i))
765 #define XIMAGE_INSTANCE_XOFFSET(i) \
766   IMAGE_INSTANCE_XOFFSET (XIMAGE_INSTANCE (i))
767 #define XIMAGE_INSTANCE_YOFFSET(i) \
768   IMAGE_INSTANCE_YOFFSET (XIMAGE_INSTANCE (i))
769 #define XIMAGE_INSTANCE_DIRTYP(i) \
770   IMAGE_INSTANCE_DIRTYP (XIMAGE_INSTANCE (i))
771 #define XIMAGE_INSTANCE_NEEDS_LAYOUT(i) \
772   IMAGE_INSTANCE_NEEDS_LAYOUT (XIMAGE_INSTANCE (i))
773 #define XIMAGE_INSTANCE_WIDTH(i) \
774   IMAGE_INSTANCE_WIDTH (XIMAGE_INSTANCE (i))
775 #define XIMAGE_INSTANCE_MARGIN_WIDTH(i) \
776   IMAGE_INSTANCE_MARGIN_WIDTH (XIMAGE_INSTANCE (i))
777 #define XIMAGE_INSTANCE_HEIGHT(i) \
778   IMAGE_INSTANCE_HEIGHT (XIMAGE_INSTANCE (i))
779 #define XIMAGE_INSTANCE_INITIALIZED(i) \
780   IMAGE_INSTANCE_INITIALIZED (XIMAGE_INSTANCE (i))
781 #define XIMAGE_INSTANCE_FACE(i) \
782   IMAGE_INSTANCE_FACE (XIMAGE_INSTANCE (i))
783
784 #define XIMAGE_INSTANCE_TEXT_STRING(i) \
785   IMAGE_INSTANCE_TEXT_STRING (XIMAGE_INSTANCE (i))
786 #define XIMAGE_INSTANCE_TEXT_WIDTH(i) \
787   IMAGE_INSTANCE_TEXT_WIDTH (XIMAGE_INSTANCE (i))
788 #define XIMAGE_INSTANCE_TEXT_HEIGHT(i) \
789   IMAGE_INSTANCE_TEXT_HEIGHT (XIMAGE_INSTANCE (i))
790 #define XIMAGE_INSTANCE_TEXT_ASCENT(i) \
791   IMAGE_INSTANCE_TEXT_ASCENT (XIMAGE_INSTANCE (i))
792 #define XIMAGE_INSTANCE_TEXT_DESCENT(i) \
793   IMAGE_INSTANCE_TEXT_DESCENT (XIMAGE_INSTANCE (i))
794
795 #define XIMAGE_INSTANCE_PIXMAP_WIDTH(i) \
796   IMAGE_INSTANCE_PIXMAP_WIDTH (XIMAGE_INSTANCE (i))
797 #define XIMAGE_INSTANCE_PIXMAP_HEIGHT(i) \
798   IMAGE_INSTANCE_PIXMAP_HEIGHT (XIMAGE_INSTANCE (i))
799 #define XIMAGE_INSTANCE_PIXMAP_DEPTH(i) \
800   IMAGE_INSTANCE_PIXMAP_DEPTH (XIMAGE_INSTANCE (i))
801 #define XIMAGE_INSTANCE_PIXMAP_FILENAME(i) \
802   IMAGE_INSTANCE_PIXMAP_FILENAME (XIMAGE_INSTANCE (i))
803 #define XIMAGE_INSTANCE_PIXMAP_MASK_FILENAME(i) \
804   IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (XIMAGE_INSTANCE (i))
805 #define XIMAGE_INSTANCE_PIXMAP_HOTSPOT_X(i) \
806   IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (XIMAGE_INSTANCE (i))
807 #define XIMAGE_INSTANCE_PIXMAP_HOTSPOT_Y(i) \
808   IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (XIMAGE_INSTANCE (i))
809 #define XIMAGE_INSTANCE_PIXMAP_FG(i) \
810   IMAGE_INSTANCE_PIXMAP_FG (XIMAGE_INSTANCE (i))
811 #define XIMAGE_INSTANCE_PIXMAP_BG(i) \
812   IMAGE_INSTANCE_PIXMAP_BG (XIMAGE_INSTANCE (i))
813 #define XIMAGE_INSTANCE_PIXMAP_MASK(i) \
814   IMAGE_INSTANCE_PIXMAP_MASK (XIMAGE_INSTANCE (i))
815 #define XIMAGE_INSTANCE_PIXMAP_SLICE(i) \
816   IMAGE_INSTANCE_PIXMAP_SLICE (XIMAGE_INSTANCE (i))
817 #define XIMAGE_INSTANCE_PIXMAP_MAXSLICE(i) \
818   IMAGE_INSTANCE_PIXMAP_MAXSLICE (XIMAGE_INSTANCE (i))
819 #define XIMAGE_INSTANCE_PIXMAP_TIMEOUT(i) \
820   IMAGE_INSTANCE_PIXMAP_TIMEOUT (XIMAGE_INSTANCE (i))
821
822 #define XIMAGE_INSTANCE_WIDGET_WIDTH(i) \
823   IMAGE_INSTANCE_WIDGET_WIDTH (XIMAGE_INSTANCE (i))
824 #define XIMAGE_INSTANCE_WIDGET_HEIGHT(i) \
825   IMAGE_INSTANCE_WIDGET_HEIGHT (XIMAGE_INSTANCE (i))
826 #define XIMAGE_INSTANCE_WIDGET_WIDTH_SUBR(i) \
827   IMAGE_INSTANCE_WIDGET_WIDTH_SUBR (XIMAGE_INSTANCE (i))
828 #define XIMAGE_INSTANCE_WIDGET_HEIGHT_SUBR(i) \
829   IMAGE_INSTANCE_WIDGET_HEIGHT_SUBR (XIMAGE_INSTANCE (i))
830 #define XIMAGE_INSTANCE_WIDGET_TYPE(i) \
831   IMAGE_INSTANCE_WIDGET_TYPE (XIMAGE_INSTANCE (i))
832 #define XIMAGE_INSTANCE_WIDGET_PROPS(i) \
833   IMAGE_INSTANCE_WIDGET_PROPS (XIMAGE_INSTANCE (i))
834 #define XIMAGE_INSTANCE_WIDGET_FACE(i) \
835   IMAGE_INSTANCE_WIDGET_FACE (XIMAGE_INSTANCE (i))
836 #define XSET_IMAGE_INSTANCE_WIDGET_FACE(i) \
837   SET_IMAGE_INSTANCE_WIDGET_FACE (XIMAGE_INSTANCE (i))
838 #define XIMAGE_INSTANCE_WIDGET_ITEM(i) \
839   IMAGE_INSTANCE_WIDGET_ITEM (XIMAGE_INSTANCE (i))
840 #define XIMAGE_INSTANCE_WIDGET_ITEMS(i) \
841   IMAGE_INSTANCE_WIDGET_ITEMS (XIMAGE_INSTANCE (i))
842 #define XIMAGE_INSTANCE_WIDGET_PENDING_ITEMS(i) \
843   IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (XIMAGE_INSTANCE (i))
844 #define XIMAGE_INSTANCE_WIDGET_TEXT(i) \
845   IMAGE_INSTANCE_WIDGET_TEXT (XIMAGE_INSTANCE (i))
846 #define XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED(i) \
847   IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (XIMAGE_INSTANCE (i))
848
849 #define XIMAGE_INSTANCE_LAYOUT_CHILDREN(i) \
850   IMAGE_INSTANCE_LAYOUT_CHILDREN (XIMAGE_INSTANCE (i))
851 #define XIMAGE_INSTANCE_LAYOUT_BORDER(i) \
852   IMAGE_INSTANCE_LAYOUT_BORDER (XIMAGE_INSTANCE (i))
853
854 #define XIMAGE_INSTANCE_SUBWINDOW_ID(i) \
855   IMAGE_INSTANCE_SUBWINDOW_ID (XIMAGE_INSTANCE (i))
856 #define XIMAGE_INSTANCE_DISPLAY_X(i) \
857   IMAGE_INSTANCE_DISPLAY_X (XIMAGE_INSTANCE (i))
858 #define XIMAGE_INSTANCE_DISPLAY_Y(i) \
859   IMAGE_INSTANCE_DISPLAY_Y (XIMAGE_INSTANCE (i))
860 #define XIMAGE_INSTANCE_DISPLAY_WIDTH(i) \
861   IMAGE_INSTANCE_DISPLAY_WIDTH (XIMAGE_INSTANCE (i))
862 #define XIMAGE_INSTANCE_DISPLAY_HEIGHT(i) \
863   IMAGE_INSTANCE_DISPLAY_HEIGHT (XIMAGE_INSTANCE (i))
864 #define XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
865   IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (XIMAGE_INSTANCE (i))
866 #define XIMAGE_INSTANCE_SUBWINDOW_ORIENT(i) \
867   IMAGE_INSTANCE_SUBWINDOW_ORIENT (XIMAGE_INSTANCE (i))
868 #define XIMAGE_INSTANCE_SUBWINDOW_JUSTIFY(i) \
869   IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (XIMAGE_INSTANCE (i))
870 #define XIMAGE_INSTANCE_SUBWINDOW_FACE(i) \
871   IMAGE_INSTANCE_SUBWINDOW_FACE (XIMAGE_INSTANCE (i))
872
873 #define MARK_IMAGE_INSTANCE_CHANGED(i) \
874   (IMAGE_INSTANCE_DIRTYP (i) = 1);
875
876 Lisp_Object image_instance_device (Lisp_Object instance);
877 Lisp_Object image_instance_frame (Lisp_Object instance);
878 Lisp_Object image_instance_window (Lisp_Object instance);
879 int image_instance_live_p (Lisp_Object instance);
880
881 #ifdef HAVE_XPM
882 Lisp_Object evaluate_xpm_color_symbols (void);
883 Lisp_Object pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid);
884 #endif /* HAVE_XPM */
885 #ifdef HAVE_WINDOW_SYSTEM
886 Lisp_Object bitmap_to_lisp_data (Lisp_Object name, int *xhot, int *yhot,
887                                  int ok_if_data_invalid);
888 int read_bitmap_data_from_file (const char *filename, unsigned int *width,
889                                 unsigned int *height, unsigned char **datap,
890                                 int *x_hot, int *y_hot);
891 Lisp_Object xbm_mask_file_munging (Lisp_Object alist, Lisp_Object file,
892                                    Lisp_Object mask_file,
893                                    Lisp_Object console_type);
894 #endif
895
896 /************************************************************************/
897 /*                              Glyph Object                            */
898 /************************************************************************/
899
900 enum glyph_type
901 {
902   GLYPH_UNKNOWN,
903   GLYPH_BUFFER,
904   GLYPH_POINTER,
905   GLYPH_ICON
906 };
907
908 struct Lisp_Glyph
909 {
910   struct lcrecord_header header;
911
912   enum glyph_type type;
913
914   /* specifiers: */
915   Lisp_Object image;            /* the actual image */
916   Lisp_Object contrib_p;        /* whether to figure into line height */
917   Lisp_Object baseline;         /* percent above baseline */
918
919   Lisp_Object face;             /* if non-nil, face to use when displaying */
920
921   Lisp_Object plist;
922   void (*after_change) (Lisp_Object glyph, Lisp_Object property,
923                         Lisp_Object locale);
924
925   unsigned int dirty : 1;       /* So that we can selectively
926                                    redisplay changed glyphs. */
927 };
928 typedef struct Lisp_Glyph Lisp_Glyph;
929
930 DECLARE_LRECORD (glyph, Lisp_Glyph);
931 #define XGLYPH(x) XRECORD (x, glyph, Lisp_Glyph)
932 #define XSETGLYPH(x, p) XSETRECORD (x, p, glyph)
933 #define GLYPHP(x) RECORDP (x, glyph)
934 #define CHECK_GLYPH(x) CHECK_RECORD (x, glyph)
935 #define CONCHECK_GLYPH(x) CONCHECK_RECORD (x, glyph)
936
937 #define CHECK_BUFFER_GLYPH(x) do {                      \
938   CHECK_GLYPH (x);                                      \
939   if (XGLYPH (x)->type != GLYPH_BUFFER)                 \
940     x = wrong_type_argument (Qbuffer_glyph_p, (x));     \
941 } while (0)
942
943 #define CHECK_POINTER_GLYPH(x) do {                     \
944   CHECK_GLYPH (x);                                      \
945   if (XGLYPH (x)->type != GLYPH_POINTER)                \
946     x = wrong_type_argument (Qpointer_glyph_p, (x));    \
947 } while (0)
948
949 #define CHECK_ICON_GLYPH(x) do {                        \
950   CHECK_GLYPH (x);                                      \
951   if (XGLYPH (x)->type != GLYPH_ICON)                   \
952     x = wrong_type_argument (Qicon_glyph_p, (x));       \
953 } while (0)
954
955 #define GLYPH_TYPE(g) ((g)->type)
956 #define GLYPH_IMAGE(g) ((g)->image)
957 #define GLYPH_CONTRIB_P(g) ((g)->contrib_p)
958 #define GLYPH_BASELINE(g) ((g)->baseline)
959 #define GLYPH_FACE(g) ((g)->face)
960 #define GLYPH_DIRTYP(g) ((g)->dirty)
961
962 #define XGLYPH_TYPE(g) GLYPH_TYPE (XGLYPH (g))
963 #define XGLYPH_IMAGE(g) GLYPH_IMAGE (XGLYPH (g))
964 #define XGLYPH_CONTRIB_P(g) GLYPH_CONTRIB_P (XGLYPH (g))
965 #define XGLYPH_BASELINE(g) GLYPH_BASELINE (XGLYPH (g))
966 #define XGLYPH_FACE(g) GLYPH_FACE (XGLYPH (g))
967 #define XGLYPH_DIRTYP(g) GLYPH_DIRTYP (XGLYPH (g))
968
969 #define MARK_GLYPH_CHANGED(g) (GLYPH_DIRTYP (g) = 1);
970
971 extern Lisp_Object Qxpm, Qxface, Qetched_in, Qetched_out, Qbevel_in, Qbevel_out;
972 extern Lisp_Object Q_data, Q_file, Q_color_symbols, Qconst_glyph_variable;
973 extern Lisp_Object Qxbm, Qedit_field, Qgroup, Qlabel, Qcombo_box, Qscrollbar;
974 extern Lisp_Object Qtree_view, Qtab_control, Qprogress_gauge, Q_border;
975 extern Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y;
976 extern Lisp_Object Q_foreground, Q_background, Q_face, Q_descriptor, Q_group;
977 extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height, Q_text;
978 extern Lisp_Object Q_items, Q_properties, Q_image, Qimage_conversion_error;
979 extern Lisp_Object Q_orientation, Q_margin_width;
980 extern Lisp_Object Vcontinuation_glyph, Vcontrol_arrow_glyph, Vhscroll_glyph;
981 extern Lisp_Object Vinvisible_text_glyph, Voctal_escape_glyph, Vtruncation_glyph;
982 extern Lisp_Object Vxemacs_logo;
983
984
985 unsigned short glyph_width (Lisp_Object glyph, Lisp_Object domain);
986 unsigned short glyph_ascent (Lisp_Object glyph, Lisp_Object domain);
987 unsigned short glyph_descent (Lisp_Object glyph, Lisp_Object domain);
988 unsigned short glyph_height (Lisp_Object glyph, Lisp_Object domain);
989 Lisp_Object glyph_baseline (Lisp_Object glyph, Lisp_Object domain);
990 Lisp_Object glyph_face (Lisp_Object glyph, Lisp_Object domain);
991 int glyph_contrib_p (Lisp_Object glyph, Lisp_Object domain);
992 Lisp_Object glyph_image_instance (Lisp_Object glyph,
993                                   Lisp_Object domain,
994                                   Error_behavior errb, int no_quit);
995 void file_or_data_must_be_present (Lisp_Object instantiator);
996 void data_must_be_present (Lisp_Object instantiator);
997 Lisp_Object make_string_from_file (Lisp_Object file);
998 Lisp_Object tagged_vector_to_alist (Lisp_Object vector);
999 Lisp_Object alist_to_tagged_vector (Lisp_Object tag, Lisp_Object alist);
1000 void string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
1001                          Lisp_Object pointer_fg, Lisp_Object pointer_bg,
1002                          int dest_mask, Lisp_Object domain);
1003 int tab_control_order_only_changed (Lisp_Object image_instance);
1004 Lisp_Object allocate_glyph (enum glyph_type type,
1005                             void (*after_change) (Lisp_Object glyph,
1006                                                   Lisp_Object property,
1007                                                   Lisp_Object locale));
1008 Lisp_Object normalize_image_instantiator (Lisp_Object instantiator,
1009                                           Lisp_Object contype,
1010                                           Lisp_Object dest_mask);
1011 void glyph_query_geometry (Lisp_Object glyph_or_image, int* width, int* height,
1012                            enum image_instance_geometry disp,
1013                            Lisp_Object domain);
1014 void glyph_do_layout (Lisp_Object glyph_or_image, int width, int height,
1015                       int xoffset, int yoffset,
1016                       Lisp_Object domain);
1017 void query_string_geometry ( Lisp_Object string, Lisp_Object face,
1018                              int* width, int* height, int* descent,
1019                              Lisp_Object domain);
1020 Lisp_Object query_string_font (Lisp_Object string,
1021                                Lisp_Object face, Lisp_Object domain);
1022 Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object device);
1023 void disable_glyph_animated_timeout (int i);
1024
1025 /************************************************************************/
1026 /*                              Glyph Cachels                           */
1027 /************************************************************************/
1028
1029 typedef struct glyph_cachel glyph_cachel;
1030 struct glyph_cachel
1031 {
1032   Lisp_Object glyph;
1033
1034   unsigned int dirty :1;        /* I'm copying faces here. I'm not
1035                                    sure why we need two dirty
1036                                    flags. Maybe because an image
1037                                    instance can be dirty and so we
1038                                    need to frob this in the same way
1039                                    as other image instance properties.  */
1040   unsigned int updated :1;
1041
1042   unsigned short width;
1043   unsigned short ascent;
1044   unsigned short descent;
1045 };
1046
1047 #define CONT_GLYPH_INDEX        (glyph_index) 0
1048 #define TRUN_GLYPH_INDEX        (glyph_index) 1
1049 #define HSCROLL_GLYPH_INDEX     (glyph_index) 2
1050 #define CONTROL_GLYPH_INDEX     (glyph_index) 3
1051 #define OCT_ESC_GLYPH_INDEX     (glyph_index) 4
1052 #define INVIS_GLYPH_INDEX       (glyph_index) 5
1053
1054 #ifdef ERROR_CHECK_GLYPHS
1055
1056 #include "window.h"
1057
1058 INLINE_HEADER int
1059 GLYPH_CACHEL_WIDTH (struct window *window, int ind);
1060 INLINE_HEADER int
1061 GLYPH_CACHEL_WIDTH (struct window *window, int ind)
1062 {
1063   int wid = Dynarr_atp (window->glyph_cachels, ind)->width;
1064   assert (wid >= 0 && wid < 10000);
1065   return wid;
1066 }
1067 INLINE_HEADER int
1068 GLYPH_CACHEL_ASCENT (struct window *window, int ind);
1069 INLINE_HEADER int
1070 GLYPH_CACHEL_ASCENT (struct window *window, int ind)
1071 {
1072   int wid = Dynarr_atp (window->glyph_cachels, ind)->ascent;
1073   assert (wid >= 0 && wid < 10000);
1074   return wid;
1075 }
1076 INLINE_HEADER int
1077 GLYPH_CACHEL_DESCENT (struct window *window, int ind);
1078 INLINE_HEADER int
1079 GLYPH_CACHEL_DESCENT (struct window *window, int ind)
1080 {
1081   int wid = Dynarr_atp (window->glyph_cachels, ind)->descent;
1082   assert (wid >= 0 && wid < 10000);
1083   return wid;
1084 }
1085
1086 #else /* not ERROR_CHECK_GLYPHS */
1087
1088 #define GLYPH_CACHEL_WIDTH(window, ind)         \
1089   Dynarr_atp (window->glyph_cachels, ind)->width
1090 #define GLYPH_CACHEL_ASCENT(window, ind)                \
1091   Dynarr_atp (window->glyph_cachels, ind)->ascent
1092 #define GLYPH_CACHEL_DESCENT(window, ind)               \
1093   Dynarr_atp (window->glyph_cachels, ind)->descent
1094
1095 #endif /* not ERROR_CHECK_GLYPHS */
1096
1097 #define GLYPH_CACHEL(window, ind)                       \
1098   Dynarr_atp (window->glyph_cachels, ind)
1099 #define GLYPH_CACHEL_GLYPH(window, ind)         \
1100   Dynarr_atp (window->glyph_cachels, ind)->glyph
1101 #define GLYPH_CACHEL_DIRTYP(window, ind)                \
1102   Dynarr_atp (window->glyph_cachels, ind)->dirty
1103
1104 void mark_glyph_cachels (glyph_cachel_dynarr *elements);
1105 void mark_glyph_cachels_as_not_updated (struct window *w);
1106 void mark_glyph_cachels_as_clean (struct window *w);
1107 void reset_glyph_cachels (struct window *w);
1108 glyph_index get_glyph_cachel_index (struct window *w, Lisp_Object glyph);
1109
1110 #ifdef MEMORY_USAGE_STATS
1111 int compute_glyph_cachel_usage (glyph_cachel_dynarr *glyph_cachels,
1112                                 struct overhead_stats *ovstats);
1113 #endif /* MEMORY_USAGE_STATS */
1114
1115 /************************************************************************/
1116 /*                              Display Tables                          */
1117 /************************************************************************/
1118
1119 Lisp_Object display_table_entry (Emchar, Lisp_Object, Lisp_Object);
1120 void get_display_tables (struct window *, face_index,
1121                          Lisp_Object *, Lisp_Object *);
1122
1123 /****************************************************************************
1124  *                            Subwindow Object                              *
1125  ****************************************************************************/
1126
1127 void unmap_subwindow (Lisp_Object subwindow);
1128 void map_subwindow (Lisp_Object subwindow, int x, int y,
1129                     struct display_glyph_area *dga);
1130 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height);
1131 void redisplay_widget (Lisp_Object widget);
1132 void update_widget_instances (Lisp_Object frame);
1133 void redisplay_subwindow (Lisp_Object subwindow);
1134 Lisp_Object image_instance_parent_glyph (struct Lisp_Image_Instance*);
1135 int image_instance_changed (Lisp_Object image);
1136 void free_frame_subwindow_instances (struct frame* f);
1137 void reset_frame_subwindow_instance_cache (struct frame* f);
1138 int unmap_subwindow_instance_cache_mapper (Lisp_Object key,
1139                                            Lisp_Object value, void* finalize);
1140
1141 struct expose_ignore
1142 {
1143   unsigned int  x, y;
1144   unsigned int  width, height;
1145   struct expose_ignore *next;
1146 };
1147
1148 int check_for_ignored_expose (struct frame* f, int x, int y, int width, int height);
1149 extern int hold_ignored_expose_registration;
1150
1151 #endif /* INCLUDED_glyphs_h_ */