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