XEmacs 21.2.25 "Hephaestus".
[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 _XEMACS_GLYPHS_H_
25 #define _XEMACS_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
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   static                                widget
66 */
67
68 /* These are methods specific to a particular format of image instantiator
69    (e.g. xpm, string, etc.). */
70
71 typedef struct ii_keyword_entry ii_keyword_entry;
72 struct ii_keyword_entry
73 {
74   Lisp_Object keyword;
75   void (*validate) (Lisp_Object data);
76   int multiple_p;
77   int copy_p;
78 };
79
80 typedef struct
81 {
82   Dynarr_declare (ii_keyword_entry);
83 } ii_keyword_entry_dynarr;
84
85 extern const struct struct_description iim_description;
86
87 struct image_instantiator_methods
88 {
89   Lisp_Object symbol;
90
91   Lisp_Object device;           /* sometimes used */
92
93   ii_keyword_entry_dynarr *keywords;
94   /* consoles this ii is supported on */
95   console_type_entry_dynarr *consoles;
96   /* Implementation specific methods: */
97
98   /* Validate method: Given an instantiator vector, signal an error if
99      it's invalid for this image-instantiator format.  Note that this
100      validation only occurs after all the keyword-specific validation
101      has already been performed.  This is chiefly useful for making
102      sure that certain required keywords are present. */
103   void (*validate_method) (Lisp_Object instantiator);
104
105   /* Normalize method: Given an instantiator, convert it to the form
106      that should be used in a glyph, for devices of type CONSOLE_TYPE.
107      Signal an error if conversion fails. */
108   Lisp_Object (*normalize_method) (Lisp_Object instantiator,
109                                    Lisp_Object console_type);
110
111   /* Possible-dest-types method: Return a mask indicating what dest types
112      are compatible with this format. */
113   int (*possible_dest_types_method) (void);
114
115   /* Instantiate method: Given an instantiator and a partially
116      filled-in image instance, complete the filling-in.  Return
117      non-zero if the instantiation succeeds, 0 if it fails.
118      This must be present. */
119   void (*instantiate_method) (Lisp_Object image_instance,
120                               Lisp_Object instantiator,
121                               Lisp_Object pointer_fg,
122                               Lisp_Object pointer_bg,
123                               int dest_mask,
124                               Lisp_Object domain);
125   /* Property method: Given an image instance, return device specific
126      properties. */
127   Lisp_Object (*property_method) (Lisp_Object image_instance,
128                                   Lisp_Object property);
129   /* Set-property method: Given an image instance, set device specific
130      properties. */
131   Lisp_Object (*set_property_method) (Lisp_Object image_instance,
132                                       Lisp_Object property,
133                                       Lisp_Object val);
134
135   /* Find out the geometry of this image instance. */
136   void (*query_geometry_method) (Lisp_Object image_instance,
137                                  int* width, int* height, int disp);
138
139   /* Layout the instances children. */
140   void (*layout_children_method) (Lisp_Object image_instance);
141 };
142
143 /***** Calling an image-instantiator method *****/
144
145 #define HAS_IIFORMAT_METH_P(mstruc, m) (((mstruc)->m##_method) != 0)
146 #define IIFORMAT_METH(mstruc, m, args) (((mstruc)->m##_method) args)
147
148 /* Call a void-returning specifier method, if it exists */
149 #define MAYBE_IIFORMAT_METH(mstruc, m, args)                    \
150 do {                                                            \
151   struct image_instantiator_methods *MIM_mstruc = (mstruc);     \
152   if (MIM_mstruc && HAS_IIFORMAT_METH_P (MIM_mstruc, m))        \
153     IIFORMAT_METH (MIM_mstruc, m, args);                        \
154 } while (0)
155
156 #define MAYBE_IIFORMAT_DEVMETH(device, mstruc, m, args) \
157 do {                                                    \
158   struct image_instantiator_methods *MID_mstruc =       \
159     decode_ii_device (device, mstruc);                  \
160   if (MID_mstruc)                                       \
161     MAYBE_IIFORMAT_METH(MID_mstruc, m, args);           \
162 } while (0)
163
164
165 /* Call a specifier method, if it exists; otherwise return
166    the specified value */
167
168 #define IIFORMAT_METH_OR_GIVEN(mstruc, m, args, given)  \
169   (HAS_IIFORMAT_METH_P (mstruc, m) ?                    \
170    IIFORMAT_METH (mstruc, m, args) : (given))
171
172 /***** Defining new image-instantiator types *****/
173
174 #define DECLARE_IMAGE_INSTANTIATOR_FORMAT(format)               \
175 extern struct image_instantiator_methods *format##_image_instantiator_methods
176
177 #define DEFINE_IMAGE_INSTANTIATOR_FORMAT(format)                \
178 struct image_instantiator_methods *format##_image_instantiator_methods
179
180 #define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name)   \
181 do {                                                            \
182   format##_image_instantiator_methods =                         \
183     xnew_and_zero (struct image_instantiator_methods);          \
184   format##_image_instantiator_methods->symbol = Q##format;      \
185   format##_image_instantiator_methods->device = Qnil;           \
186   format##_image_instantiator_methods->keywords =               \
187     Dynarr_new (ii_keyword_entry);                              \
188   format##_image_instantiator_methods->consoles =               \
189     Dynarr_new (console_type_entry);                            \
190   add_entry_to_image_instantiator_format_list                   \
191     (Q##format, format##_image_instantiator_methods);           \
192   dumpstruct (&format##_image_instantiator_methods,             \
193               &iim_description);                                \
194 } while (0)
195
196 #define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(format, obj_name)  \
197 do {                                                            \
198   defsymbol (&Q##format, obj_name);                             \
199   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name);\
200 } while (0)
201
202 /* Declare that image-instantiator format FORMAT has method M; used in
203    initialization routines */
204 #define IIFORMAT_HAS_METHOD(format, m) \
205   (format##_image_instantiator_methods->m##_method = format##_##m)
206
207 #define IIFORMAT_HAS_SHARED_METHOD(format, m, type) \
208   (format##_image_instantiator_methods->m##_method = type##_##m)
209
210 /* Declare that KEYW is a valid keyword for image-instantiator format
211    FORMAT.  VALIDATE_FUN if a function that returns whether the data
212    is valid.  The keyword may not appear more than once. */
213 #define IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, copy, multi) \
214   do {                                                  \
215     struct ii_keyword_entry entry;                              \
216                                                         \
217     entry.keyword = keyw;                               \
218     entry.validate = validate_fun;                              \
219     entry.multiple_p = multi;                           \
220     entry.copy_p = copy;                                        \
221     Dynarr_add (format##_image_instantiator_methods->keywords,  \
222                 entry);                                         \
223   } while (0)
224
225 #define IIFORMAT_VALID_KEYWORD(format, keyw, validate_fun)      \
226 IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 1, 0)
227
228 /* Same as IIFORMAT_VALID_KEYWORD except that the keyword may
229    appear multiple times. */
230 #define IIFORMAT_VALID_MULTI_KEYWORD(format, keyw, validate_fun)        \
231 IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 1, 1)
232
233 /* Same as IIFORMAT_VALID_KEYWORD execpt that the argument is not
234    copied by the specifier functions. This is necessary for things
235    like callbacks etc. */
236 #define IIFORMAT_VALID_NONCOPY_KEYWORD(format, keyw, validate_fun)      \
237 IIFORMAT_VALID_GENERIC_KEYWORD(format, keyw, validate_fun, 0, 0)
238
239 /* Declare that image-instantiator format FORMAT is supported on 
240    CONSOLE type. */
241 #define IIFORMAT_VALID_CONSOLE(console, format)         \
242   do {                                                          \
243     struct console_type_entry entry;                            \
244                                                                 \
245     entry.symbol = Q##console;                                  \
246     entry.meths = console##_console_methods;                    \
247     Dynarr_add (format##_image_instantiator_methods->consoles,  \
248                 entry);                                         \
249   } while (0)
250
251 #define DEFINE_DEVICE_IIFORMAT(type, format)\
252 DECLARE_IMAGE_INSTANTIATOR_FORMAT(format);              \
253 struct image_instantiator_methods *type##_##format##_image_instantiator_methods
254
255 #define INITIALIZE_DEVICE_IIFORMAT(type, format)                        \
256 do {                                                                    \
257   type##_##format##_image_instantiator_methods =                        \
258     xnew_and_zero (struct image_instantiator_methods);                  \
259   type##_##format##_image_instantiator_methods->symbol = Q##format;     \
260   type##_##format##_image_instantiator_methods->device = Q##type;       \
261   type##_##format##_image_instantiator_methods->keywords =              \
262     Dynarr_new (ii_keyword_entry);                                      \
263   add_entry_to_device_ii_format_list                                    \
264     (Q##type, Q##format, type##_##format##_image_instantiator_methods); \
265   IIFORMAT_VALID_CONSOLE(type,format);                                  \
266   dumpstruct (&type##_##format##_image_instantiator_methods,            \
267               &iim_description);                                        \
268 } while (0)
269
270 /* Declare that image-instantiator format FORMAT has method M; used in
271    initialization routines */
272 #define IIFORMAT_HAS_DEVMETHOD(type, format, m) \
273   (type##_##format##_image_instantiator_methods->m##_method = type##_##format##_##m)
274 #define IIFORMAT_HAS_SHARED_DEVMETHOD(type, format, m, fromformat) \
275   (type##_##format##_image_instantiator_methods->m##_method = type##_##fromformat##_##m)
276
277 struct image_instantiator_methods *
278 decode_device_ii_format (Lisp_Object device, Lisp_Object format,
279                          Error_behavior errb);
280 struct image_instantiator_methods *
281 decode_image_instantiator_format (Lisp_Object format, Error_behavior errb);
282
283 void add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
284                         struct image_instantiator_methods *meths);
285 void add_entry_to_device_ii_format_list (Lisp_Object device, Lisp_Object symbol,
286                         struct image_instantiator_methods *meths);
287 Lisp_Object find_keyword_in_vector (Lisp_Object vector,
288                                     Lisp_Object keyword);
289 Lisp_Object find_keyword_in_vector_or_given (Lisp_Object vector,
290                                              Lisp_Object keyword,
291                                              Lisp_Object default_);
292 Lisp_Object simple_image_type_normalize (Lisp_Object inst,
293                                          Lisp_Object console_type,
294                                          Lisp_Object image_type_tag);
295 Lisp_Object potential_pixmap_file_instantiator (Lisp_Object instantiator,
296                                                 Lisp_Object file_keyword,
297                                                 Lisp_Object data_keyword,
298                                                 Lisp_Object console_type);
299 void check_valid_string (Lisp_Object data);
300 void check_valid_int (Lisp_Object data);
301 void check_valid_face (Lisp_Object data);
302 void check_valid_vector (Lisp_Object data);
303 void check_valid_item_list_1 (Lisp_Object items);
304
305 void initialize_subwindow_image_instance (struct Lisp_Image_Instance*);
306 void subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
307                             Lisp_Object pointer_fg, Lisp_Object pointer_bg,
308                             int dest_mask, Lisp_Object domain);
309 void widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
310                            Lisp_Object pointer_fg, Lisp_Object pointer_bg,
311                            int dest_mask, Lisp_Object domain, int default_textheight,
312                            int default_pixheight, int default_textwidth);
313
314 DECLARE_DOESNT_RETURN (incompatible_image_types (Lisp_Object instantiator,
315                                                  int given_dest_mask,
316                                                  int desired_dest_mask));
317 DECLARE_DOESNT_RETURN (signal_image_error (CONST char *, Lisp_Object));
318 DECLARE_DOESNT_RETURN (signal_image_error_2 (CONST char *, Lisp_Object, Lisp_Object));
319
320 /************************************************************************/
321 /*                      Image Specifier Object                          */
322 /************************************************************************/
323
324 DECLARE_SPECIFIER_TYPE (image);
325 #define XIMAGE_SPECIFIER(x) XSPECIFIER_TYPE (x, image)
326 #define XSETIMAGE_SPECIFIER(x, p) XSETSPECIFIER_TYPE (x, p, image)
327 #define IMAGE_SPECIFIERP(x) SPECIFIER_TYPEP (x, image)
328 #define CHECK_IMAGE_SPECIFIER(x) CHECK_SPECIFIER_TYPE (x, image)
329 #define CONCHECK_IMAGE_SPECIFIER(x) CONCHECK_SPECIFIER_TYPE (x, image)
330
331 void set_image_attached_to (Lisp_Object obj, Lisp_Object face_or_glyph,
332                             Lisp_Object property);
333
334 struct image_specifier
335 {
336   int allowed;
337   Lisp_Object attachee;         /* face or glyph this is attached to, or nil */
338   Lisp_Object attachee_property;/* property of that face or glyph */
339 };
340
341 #define IMAGE_SPECIFIER_DATA(g) (SPECIFIER_TYPE_DATA (g, image))
342 #define IMAGE_SPECIFIER_ALLOWED(g) (IMAGE_SPECIFIER_DATA (g)->allowed)
343 #define IMAGE_SPECIFIER_ATTACHEE(g) (IMAGE_SPECIFIER_DATA (g)->attachee)
344 #define IMAGE_SPECIFIER_ATTACHEE_PROPERTY(g) \
345   (IMAGE_SPECIFIER_DATA (g)->attachee_property)
346
347 #define XIMAGE_SPECIFIER_ALLOWED(g) \
348   IMAGE_SPECIFIER_ALLOWED (XIMAGE_SPECIFIER (g))
349
350 /************************************************************************/
351 /*                      Image Instance Object                           */
352 /************************************************************************/
353
354 DECLARE_LRECORD (image_instance, struct Lisp_Image_Instance);
355 #define XIMAGE_INSTANCE(x) \
356   XRECORD (x, image_instance, struct Lisp_Image_Instance)
357 #define XSETIMAGE_INSTANCE(x, p) XSETRECORD (x, p, image_instance)
358 #define IMAGE_INSTANCEP(x) RECORDP (x, image_instance)
359 #define CHECK_IMAGE_INSTANCE(x) CHECK_RECORD (x, image_instance)
360 #define CONCHECK_IMAGE_INSTANCE(x) CONCHECK_RECORD (x, image_instance)
361
362 enum image_instance_type
363 {
364   IMAGE_UNKNOWN,
365   IMAGE_NOTHING,
366   IMAGE_TEXT,
367   IMAGE_MONO_PIXMAP,
368   IMAGE_COLOR_PIXMAP,
369   IMAGE_POINTER,
370   IMAGE_SUBWINDOW,
371   IMAGE_WIDGET,
372   IMAGE_LAYOUT
373 };
374
375 enum image_instance_geometry
376 {
377   IMAGE_GEOMETRY,
378   IMAGE_DESIRED_GEOMETRY,
379   IMAGE_MIN_GEOMETRY,
380   IMAGE_MAX_GEOMETRY
381 };
382
383 #define IMAGE_NOTHING_MASK (1 << 0)
384 #define IMAGE_TEXT_MASK (1 << 1)
385 #define IMAGE_MONO_PIXMAP_MASK (1 << 2)
386 #define IMAGE_COLOR_PIXMAP_MASK (1 << 3)
387 #define IMAGE_POINTER_MASK (1 << 4)
388 #define IMAGE_SUBWINDOW_MASK (1 << 5)
389 #define IMAGE_WIDGET_MASK (1 << 6)
390 #define IMAGE_LAYOUT_MASK (1 << 7)
391
392 #define IMAGE_INSTANCE_TYPE_P(ii, type) \
393 (IMAGE_INSTANCEP (ii) && XIMAGE_INSTANCE_TYPE (ii) == type)
394
395 #define NOTHING_IMAGE_INSTANCEP(ii) \
396      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_NOTHING)
397 #define TEXT_IMAGE_INSTANCEP(ii) \
398      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_TEXT)
399 #define MONO_PIXMAP_IMAGE_INSTANCEP(ii) \
400      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_MONO_PIXMAP)
401 #define COLOR_PIXMAP_IMAGE_INSTANCEP(ii) \
402      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_COLOR_PIXMAP)
403 #define POINTER_IMAGE_INSTANCEP(ii) \
404      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_POINTER)
405 #define SUBWINDOW_IMAGE_INSTANCEP(ii) \
406      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_SUBWINDOW)
407 #define WIDGET_IMAGE_INSTANCEP(ii) \
408      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_WIDGET)
409 #define LAYOUT_IMAGE_INSTANCEP(ii) \
410      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_LAYOUT)
411
412 #define CHECK_NOTHING_IMAGE_INSTANCE(x) do {            \
413   CHECK_IMAGE_INSTANCE (x);                             \
414   if (!NOTHING_IMAGE_INSTANCEP (x))                             \
415     x = wrong_type_argument (Qnothing_image_instance_p, (x));   \
416 } while (0)
417
418 #define CHECK_TEXT_IMAGE_INSTANCE(x) do {               \
419   CHECK_IMAGE_INSTANCE (x);                             \
420   if (!TEXT_IMAGE_INSTANCEP (x))                                \
421     x = wrong_type_argument (Qtext_image_instance_p, (x));      \
422 } while (0)
423
424 #define CHECK_MONO_PIXMAP_IMAGE_INSTANCE(x) do {                        \
425   CHECK_IMAGE_INSTANCE (x);                                             \
426   if (!MONO_PIXMAP_IMAGE_INSTANCEP (x))                                 \
427     x = wrong_type_argument (Qmono_pixmap_image_instance_p, (x));       \
428 } while (0)
429
430 #define CHECK_COLOR_PIXMAP_IMAGE_INSTANCE(x) do {               \
431   CHECK_IMAGE_INSTANCE (x);                                     \
432   if (!COLOR_PIXMAP_IMAGE_INSTANCEP (x))                                \
433     x = wrong_type_argument (Qcolor_pixmap_image_instance_p, (x));      \
434 } while (0)
435
436 #define CHECK_POINTER_IMAGE_INSTANCE(x) do {            \
437   CHECK_IMAGE_INSTANCE (x);                             \
438   if (!POINTER_IMAGE_INSTANCEP (x))                             \
439     x = wrong_type_argument (Qpointer_image_instance_p, (x));   \
440 } while (0)
441
442 #define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do {          \
443   CHECK_IMAGE_INSTANCE (x);                                     \
444   if (!SUBWINDOW_IMAGE_INSTANCEP (x)                            \
445       && !WIDGET_IMAGE_INSTANCEP (x))                           \
446     x = wrong_type_argument (Qsubwindow_image_instance_p, (x)); \
447 } while (0)
448
449 #define CHECK_WIDGET_IMAGE_INSTANCE(x) do {             \
450   CHECK_IMAGE_INSTANCE (x);                             \
451   if (!WIDGET_IMAGE_INSTANCEP (x))                              \
452     x = wrong_type_argument (Qwidget_image_instance_p, (x));    \
453 } while (0)
454
455 #define CHECK_LAYOUT_IMAGE_INSTANCE(x) do {             \
456   CHECK_IMAGE_INSTANCE (x);                             \
457   if (!LAYOUT_IMAGE_INSTANCEP (x))                              \
458     x = wrong_type_argument (Qlayout_image_instance_p, (x));    \
459 } while (0)
460
461 struct Lisp_Image_Instance
462 {
463   struct lcrecord_header header;
464   Lisp_Object device;
465   Lisp_Object name;
466   enum image_instance_type type;
467   unsigned int x_offset, y_offset;      /* for layout purposes */
468   unsigned int width, height;
469   unsigned int dirty : 1;
470   union
471   {
472     struct
473     {
474       unsigned int descent;
475       Lisp_Object string;
476     } text;
477     struct
478     {
479       unsigned int depth;
480       unsigned int slice, maxslice, timeout;
481       Lisp_Object hotspot_x, hotspot_y; /* integer or Qnil */
482       Lisp_Object filename;      /* string or Qnil */
483       Lisp_Object mask_filename; /* string or Qnil */
484       Lisp_Object fg, bg; /* foreground and background colors,
485                              if this is a colorized mono-pixmap
486                              or a pointer */
487       Lisp_Object auxdata;    /* list or Qnil: any additional data
488                                  to be seen from lisp */
489       void* mask;               /* mask that can be seen from all windowing systems */
490     } pixmap; /* used for pointers as well */
491     struct
492     {
493       Lisp_Object frame;
494       void* subwindow;          /* specific devices can use this as necessary */
495       unsigned int being_displayed : 1; /* used to detect when needs to be unmapped */
496       union
497       {
498         struct
499         {
500           Lisp_Object face; /* foreground and background colors */
501           Lisp_Object type;
502           Lisp_Object props;    /* properties */
503           Lisp_Object gui_item; /* a list of gui_items */
504         } widget;               /* widgets are subwindows */
505         struct
506         {
507           Lisp_Object children; /* managed children */
508           Lisp_Object border;   /* Style of enclosing border or text. */
509         } layout;
510       } s;
511     } subwindow;
512   } u;
513
514   /* console-type- and image-type-specific data */
515   void *data;
516 };
517
518 #define IMAGE_INSTANCE_DEVICE(i) ((i)->device)
519 #define IMAGE_INSTANCE_NAME(i) ((i)->name)
520 #define IMAGE_INSTANCE_TYPE(i) ((i)->type)
521 #define IMAGE_INSTANCE_XOFFSET(i) ((i)->x_offset)
522 #define IMAGE_INSTANCE_YOFFSET(i) ((i)->y_offset)
523 #define IMAGE_INSTANCE_WIDTH(i) ((i)->width)
524 #define IMAGE_INSTANCE_HEIGHT(i) ((i)->height)
525 #define IMAGE_INSTANCE_PIXMAP_TYPE_P(i)                                 \
526  ((IMAGE_INSTANCE_TYPE (i) == IMAGE_MONO_PIXMAP)                        \
527   || (IMAGE_INSTANCE_TYPE (i) == IMAGE_COLOR_PIXMAP))
528 #define IMAGE_INSTANCE_DIRTYP(i) ((i)->dirty)
529
530 #define IMAGE_INSTANCE_TEXT_STRING(i) ((i)->u.text.string)
531 #define IMAGE_INSTANCE_TEXT_WIDTH(i) \
532   IMAGE_INSTANCE_WIDTH(i)
533 #define IMAGE_INSTANCE_TEXT_HEIGHT(i) \
534   IMAGE_INSTANCE_HEIGHT(i)
535 #define IMAGE_INSTANCE_TEXT_DESCENT(i) ((i)->u.text.descent)
536
537 #define IMAGE_INSTANCE_PIXMAP_WIDTH(i) \
538   IMAGE_INSTANCE_WIDTH(i)
539 #define IMAGE_INSTANCE_PIXMAP_HEIGHT(i) \
540   IMAGE_INSTANCE_HEIGHT(i)
541 #define IMAGE_INSTANCE_PIXMAP_DEPTH(i) ((i)->u.pixmap.depth)
542 #define IMAGE_INSTANCE_PIXMAP_FILENAME(i) ((i)->u.pixmap.filename)
543 #define IMAGE_INSTANCE_PIXMAP_MASK_FILENAME(i) ((i)->u.pixmap.mask_filename)
544 #define IMAGE_INSTANCE_PIXMAP_HOTSPOT_X(i) ((i)->u.pixmap.hotspot_x)
545 #define IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y(i) ((i)->u.pixmap.hotspot_y)
546 #define IMAGE_INSTANCE_PIXMAP_FG(i) ((i)->u.pixmap.fg)
547 #define IMAGE_INSTANCE_PIXMAP_BG(i) ((i)->u.pixmap.bg)
548 #define IMAGE_INSTANCE_PIXMAP_AUXDATA(i) ((i)->u.pixmap.auxdata)
549 #define IMAGE_INSTANCE_PIXMAP_MASK(i) ((i)->u.pixmap.mask)
550 #define IMAGE_INSTANCE_PIXMAP_SLICE(i) ((i)->u.pixmap.slice)
551 #define IMAGE_INSTANCE_PIXMAP_MAXSLICE(i) ((i)->u.pixmap.maxslice)
552 #define IMAGE_INSTANCE_PIXMAP_TIMEOUT(i) ((i)->u.pixmap.timeout)
553
554 #define IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) \
555  IMAGE_INSTANCE_WIDTH(i)
556 #define IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) \
557   IMAGE_INSTANCE_HEIGHT(i)
558 #define IMAGE_INSTANCE_SUBWINDOW_ID(i) ((i)->u.subwindow.subwindow)
559 #define IMAGE_INSTANCE_SUBWINDOW_FRAME(i) ((i)->u.subwindow.frame)
560 #define IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
561 ((i)->u.subwindow.being_displayed)
562
563 #define IMAGE_INSTANCE_WIDGET_WIDTH(i) \
564   IMAGE_INSTANCE_WIDTH(i)
565 #define IMAGE_INSTANCE_WIDGET_HEIGHT(i) \
566   IMAGE_INSTANCE_HEIGHT(i)
567 #define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.s.widget.type)
568 #define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.s.widget.props)
569 #define IMAGE_INSTANCE_WIDGET_FACE(i) ((i)->u.subwindow.s.widget.face)
570 #define IMAGE_INSTANCE_WIDGET_ITEMS(i) ((i)->u.subwindow.s.widget.gui_item)
571 #define IMAGE_INSTANCE_WIDGET_ITEM(i) \
572 (CONSP (IMAGE_INSTANCE_WIDGET_ITEMS (i)) ? \
573 XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (i)) : \
574   IMAGE_INSTANCE_WIDGET_ITEMS (i))
575 #define IMAGE_INSTANCE_WIDGET_TEXT(i) XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (i))->name
576
577 #define IMAGE_INSTANCE_LAYOUT_CHILDREN(i) ((i)->u.subwindow.s.layout.children)
578 #define IMAGE_INSTANCE_LAYOUT_BORDER(i) ((i)->u.subwindow.s.layout.border)
579
580 #define XIMAGE_INSTANCE_DEVICE(i) \
581   IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (i))
582 #define XIMAGE_INSTANCE_NAME(i) \
583   IMAGE_INSTANCE_NAME (XIMAGE_INSTANCE (i))
584 #define XIMAGE_INSTANCE_TYPE(i) \
585   IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (i))
586 #define XIMAGE_INSTANCE_XOFFSET(i) \
587   IMAGE_INSTANCE_XOFFSET (XIMAGE_INSTANCE (i))
588 #define XIMAGE_INSTANCE_YOFFSET(i) \
589   IMAGE_INSTANCE_YOFFSET (XIMAGE_INSTANCE (i))
590 #define XIMAGE_INSTANCE_DIRTYP(i) \
591   IMAGE_INSTANCE_DIRTYP (XIMAGE_INSTANCE (i))
592
593 #define XIMAGE_INSTANCE_TEXT_STRING(i) \
594   IMAGE_INSTANCE_TEXT_STRING (XIMAGE_INSTANCE (i))
595
596 #define XIMAGE_INSTANCE_PIXMAP_WIDTH(i) \
597   IMAGE_INSTANCE_PIXMAP_WIDTH (XIMAGE_INSTANCE (i))
598 #define XIMAGE_INSTANCE_PIXMAP_HEIGHT(i) \
599   IMAGE_INSTANCE_PIXMAP_HEIGHT (XIMAGE_INSTANCE (i))
600 #define XIMAGE_INSTANCE_PIXMAP_DEPTH(i) \
601   IMAGE_INSTANCE_PIXMAP_DEPTH (XIMAGE_INSTANCE (i))
602 #define XIMAGE_INSTANCE_PIXMAP_FILENAME(i) \
603   IMAGE_INSTANCE_PIXMAP_FILENAME (XIMAGE_INSTANCE (i))
604 #define XIMAGE_INSTANCE_PIXMAP_MASK_FILENAME(i) \
605   IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (XIMAGE_INSTANCE (i))
606 #define XIMAGE_INSTANCE_PIXMAP_HOTSPOT_X(i) \
607   IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (XIMAGE_INSTANCE (i))
608 #define XIMAGE_INSTANCE_PIXMAP_HOTSPOT_Y(i) \
609   IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (XIMAGE_INSTANCE (i))
610 #define XIMAGE_INSTANCE_PIXMAP_FG(i) \
611   IMAGE_INSTANCE_PIXMAP_FG (XIMAGE_INSTANCE (i))
612 #define XIMAGE_INSTANCE_PIXMAP_BG(i) \
613   IMAGE_INSTANCE_PIXMAP_BG (XIMAGE_INSTANCE (i))
614 #define XIMAGE_INSTANCE_PIXMAP_MASK(i) \
615   IMAGE_INSTANCE_PIXMAP_MASK (XIMAGE_INSTANCE (i))
616 #define XIMAGE_INSTANCE_PIXMAP_SLICE(i) \
617   IMAGE_INSTANCE_PIXMAP_SLICE (XIMAGE_INSTANCE (i))
618 #define XIMAGE_INSTANCE_PIXMAP_MAXSLICE(i) \
619   IMAGE_INSTANCE_PIXMAP_MAXSLICE (XIMAGE_INSTANCE (i))
620 #define XIMAGE_INSTANCE_PIXMAP_TIMEOUT(i) \
621   IMAGE_INSTANCE_PIXMAP_TIMEOUT (XIMAGE_INSTANCE (i))
622
623 #define XIMAGE_INSTANCE_WIDGET_WIDTH(i) \
624   IMAGE_INSTANCE_WIDGET_WIDTH (XIMAGE_INSTANCE (i))
625 #define XIMAGE_INSTANCE_WIDGET_HEIGHT(i) \
626   IMAGE_INSTANCE_WIDGET_HEIGHT (XIMAGE_INSTANCE (i))
627 #define XIMAGE_INSTANCE_WIDGET_TYPE(i) \
628   IMAGE_INSTANCE_WIDGET_TYPE (XIMAGE_INSTANCE (i))
629 #define XIMAGE_INSTANCE_WIDGET_PROPS(i) \
630   IMAGE_INSTANCE_WIDGET_PROPS (XIMAGE_INSTANCE (i))
631 #define XIMAGE_INSTANCE_WIDGET_FACE(i) \
632   IMAGE_INSTANCE_WIDGET_FACE (XIMAGE_INSTANCE (i))
633 #define XIMAGE_INSTANCE_WIDGET_ITEM(i) \
634   IMAGE_INSTANCE_WIDGET_ITEM (XIMAGE_INSTANCE (i))
635 #define XIMAGE_INSTANCE_WIDGET_ITEMS(i) \
636   IMAGE_INSTANCE_WIDGET_ITEMS (XIMAGE_INSTANCE (i))
637 #define XIMAGE_INSTANCE_WIDGET_TEXT(i) \
638   IMAGE_INSTANCE_WIDGET_TEXT (XIMAGE_INSTANCE (i))
639
640 #define XIMAGE_INSTANCE_LAYOUT_CHILDREN(i) \
641   IMAGE_INSTANCE_LAYOUT_CHILDREN (XIMAGE_INSTANCE (i))
642 #define XIMAGE_INSTANCE_LAYOUT_BORDER(i) \
643   IMAGE_INSTANCE_LAYOUT_BORDER (XIMAGE_INSTANCE (i))
644
645 #define XIMAGE_INSTANCE_SUBWINDOW_WIDTH(i) \
646   IMAGE_INSTANCE_SUBWINDOW_WIDTH (XIMAGE_INSTANCE (i))
647 #define XIMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) \
648   IMAGE_INSTANCE_SUBWINDOW_HEIGHT (XIMAGE_INSTANCE (i))
649 #define XIMAGE_INSTANCE_SUBWINDOW_ID(i) \
650   IMAGE_INSTANCE_SUBWINDOW_ID (XIMAGE_INSTANCE (i))
651 #define XIMAGE_INSTANCE_SUBWINDOW_FRAME(i) \
652   IMAGE_INSTANCE_SUBWINDOW_FRAME (XIMAGE_INSTANCE (i))
653 #define XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
654   IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (XIMAGE_INSTANCE (i))
655
656 #define MARK_IMAGE_INSTANCE_CHANGED(i) \
657   (IMAGE_INSTANCE_DIRTYP (i) = 1);
658
659 #ifdef HAVE_XPM
660 Lisp_Object evaluate_xpm_color_symbols (void);
661 Lisp_Object pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid);
662 #endif /* HAVE_XPM */
663 #ifdef HAVE_WINDOW_SYSTEM
664 Lisp_Object bitmap_to_lisp_data (Lisp_Object name, int *xhot, int *yhot,
665                                  int ok_if_data_invalid);
666 int read_bitmap_data_from_file (CONST char *filename, unsigned int *width,
667                                 unsigned int *height, unsigned char **datap,
668                                 int *x_hot, int *y_hot);
669 Lisp_Object xbm_mask_file_munging (Lisp_Object alist, Lisp_Object file,
670                                    Lisp_Object mask_file,
671                                    Lisp_Object console_type);
672 #endif
673
674 /************************************************************************/
675 /*                              Glyph Object                            */
676 /************************************************************************/
677
678 enum glyph_type
679 {
680   GLYPH_UNKNOWN,
681   GLYPH_BUFFER,
682   GLYPH_POINTER,
683   GLYPH_ICON
684 };
685
686 struct Lisp_Glyph
687 {
688   struct lcrecord_header header;
689
690   enum glyph_type type;
691
692   /* specifiers: */
693   Lisp_Object image;            /* the actual image */
694   Lisp_Object contrib_p;        /* whether to figure into line height */
695   Lisp_Object baseline;         /* percent above baseline */
696
697   Lisp_Object face;             /* if non-nil, face to use when displaying */
698   
699   Lisp_Object plist;
700   void (*after_change) (Lisp_Object glyph, Lisp_Object property,
701                         Lisp_Object locale);
702
703   unsigned int dirty : 1;       /* So that we can selectively
704                                    redisplay changed glyphs. */
705 };
706
707 DECLARE_LRECORD (glyph, struct Lisp_Glyph);
708 #define XGLYPH(x) XRECORD (x, glyph, struct Lisp_Glyph)
709 #define XSETGLYPH(x, p) XSETRECORD (x, p, glyph)
710 #define GLYPHP(x) RECORDP (x, glyph)
711 #define CHECK_GLYPH(x) CHECK_RECORD (x, glyph)
712 #define CONCHECK_GLYPH(x) CONCHECK_RECORD (x, glyph)
713
714 #define CHECK_BUFFER_GLYPH(x) do {                      \
715   CHECK_GLYPH (x);                                      \
716   if (XGLYPH (x)->type != GLYPH_BUFFER)                 \
717     x = wrong_type_argument (Qbuffer_glyph_p, (x));     \
718 } while (0)
719
720 #define CHECK_POINTER_GLYPH(x) do {                     \
721   CHECK_GLYPH (x);                                      \
722   if (XGLYPH (x)->type != GLYPH_POINTER)                \
723     x = wrong_type_argument (Qpointer_glyph_p, (x));    \
724 } while (0)
725
726 #define CHECK_ICON_GLYPH(x) do {                        \
727   CHECK_GLYPH (x);                                      \
728   if (XGLYPH (x)->type != GLYPH_ICON)                   \
729     x = wrong_type_argument (Qicon_glyph_p, (x));       \
730 } while (0)
731
732 #define GLYPH_TYPE(g) ((g)->type)
733 #define GLYPH_IMAGE(g) ((g)->image)
734 #define GLYPH_CONTRIB_P(g) ((g)->contrib_p)
735 #define GLYPH_BASELINE(g) ((g)->baseline)
736 #define GLYPH_FACE(g) ((g)->face)
737 #define GLYPH_DIRTYP(g) ((g)->dirty)
738
739 #define XGLYPH_TYPE(g) GLYPH_TYPE (XGLYPH (g))
740 #define XGLYPH_IMAGE(g) GLYPH_IMAGE (XGLYPH (g))
741 #define XGLYPH_CONTRIB_P(g) GLYPH_CONTRIB_P (XGLYPH (g))
742 #define XGLYPH_BASELINE(g) GLYPH_BASELINE (XGLYPH (g))
743 #define XGLYPH_FACE(g) GLYPH_FACE (XGLYPH (g))
744 #define XGLYPH_DIRTYP(g) GLYPH_DIRTYP (XGLYPH (g))
745
746 #define MARK_GLYPH_CHANGED(g) (GLYPH_DIRTYP (g) = 1);
747
748 extern Lisp_Object Qxpm, Qxface, Qetched_in, Qetched_out, Qbevel_in, Qbevel_out;
749 extern Lisp_Object Q_data, Q_file, Q_color_symbols, Qconst_glyph_variable;
750 extern Lisp_Object Qxbm, Qedit_field, Qgroup, Qlabel, Qcombo_box, Qscrollbar;
751 extern Lisp_Object Qtree_view, Qtab_control, Qprogress_gauge, Q_border;
752 extern Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y;
753 extern Lisp_Object Q_foreground, Q_background, Q_face, Q_descriptor, Q_group;
754 extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height, Q_text;
755 extern Lisp_Object Q_items, Q_properties, Q_image, Q_percent, Qimage_conversion_error;
756 extern Lisp_Object Q_orientation;
757 extern Lisp_Object Vcontinuation_glyph, Vcontrol_arrow_glyph, Vhscroll_glyph;
758 extern Lisp_Object Vinvisible_text_glyph, Voctal_escape_glyph, Vtruncation_glyph;
759 extern Lisp_Object Vxemacs_logo;
760
761 unsigned short glyph_width (Lisp_Object glyph, Lisp_Object frame_face,
762                             face_index window_findex,
763                             Lisp_Object window);
764 unsigned short glyph_ascent (Lisp_Object glyph,  Lisp_Object frame_face,
765                              face_index window_findex,
766                              Lisp_Object window);
767 unsigned short glyph_descent (Lisp_Object glyph,
768                               Lisp_Object frame_face,
769                               face_index window_findex,
770                               Lisp_Object window);
771 unsigned short glyph_height (Lisp_Object glyph,  Lisp_Object frame_face,
772                              face_index window_findex,
773                              Lisp_Object window);
774 Lisp_Object glyph_baseline (Lisp_Object glyph, Lisp_Object domain);
775 Lisp_Object glyph_face (Lisp_Object glyph, Lisp_Object domain);
776 int glyph_contrib_p (Lisp_Object glyph, Lisp_Object domain);
777 Lisp_Object glyph_image_instance (Lisp_Object glyph,
778                                   Lisp_Object domain,
779                                   Error_behavior errb, int no_quit);
780 void file_or_data_must_be_present (Lisp_Object instantiator);
781 void data_must_be_present (Lisp_Object instantiator);
782 Lisp_Object make_string_from_file (Lisp_Object file);
783 Lisp_Object tagged_vector_to_alist (Lisp_Object vector);
784 Lisp_Object alist_to_tagged_vector (Lisp_Object tag, Lisp_Object alist);
785 void string_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
786                          Lisp_Object pointer_fg, Lisp_Object pointer_bg,
787                          int dest_mask, Lisp_Object domain);
788 Lisp_Object allocate_glyph (enum glyph_type type,
789                             void (*after_change) (Lisp_Object glyph,
790                                                   Lisp_Object property,
791                                                   Lisp_Object locale));
792 Lisp_Object widget_face_font_info (Lisp_Object domain, Lisp_Object face,
793                                    int *height, int *width);
794 void widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
795                                       int th, int tw,
796                                       int* height, int* width);
797 Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object device);
798 void disable_glyph_animated_timeout (int i);
799
800 /************************************************************************/
801 /*                              Glyph Cachels                           */
802 /************************************************************************/
803
804 typedef struct glyph_cachel glyph_cachel;
805 struct glyph_cachel
806 {
807   Lisp_Object glyph;
808
809   unsigned int dirty :1;        /* I'm copying faces here. I'm not
810                                    sure why we need two dirty
811                                    flags. Maybe because an image
812                                    instance can be dirty and so we
813                                    need to frob this in the same way
814                                    as other image instance properties.  */
815   unsigned int updated :1;
816
817   unsigned short width;
818   unsigned short ascent;
819   unsigned short descent;
820 };
821
822 #define CONT_GLYPH_INDEX        (glyph_index) 0
823 #define TRUN_GLYPH_INDEX        (glyph_index) 1
824 #define HSCROLL_GLYPH_INDEX     (glyph_index) 2
825 #define CONTROL_GLYPH_INDEX     (glyph_index) 3
826 #define OCT_ESC_GLYPH_INDEX     (glyph_index) 4
827 #define INVIS_GLYPH_INDEX       (glyph_index) 5
828
829 #define GLYPH_CACHEL(window, index)                     \
830   Dynarr_atp (window->glyph_cachels, index)
831 #define GLYPH_CACHEL_GLYPH(window, index)               \
832   Dynarr_atp (window->glyph_cachels, index)->glyph
833 #define GLYPH_CACHEL_WIDTH(window, index)               \
834   Dynarr_atp (window->glyph_cachels, index)->width
835 #define GLYPH_CACHEL_ASCENT(window, index)              \
836   Dynarr_atp (window->glyph_cachels, index)->ascent
837 #define GLYPH_CACHEL_DESCENT(window, index)             \
838   Dynarr_atp (window->glyph_cachels, index)->descent
839 #define GLYPH_CACHEL_DIRTYP(window, index)              \
840   Dynarr_atp (window->glyph_cachels, index)->dirty
841
842 void mark_glyph_cachels (glyph_cachel_dynarr *elements);
843 void mark_glyph_cachels_as_not_updated (struct window *w);
844 void mark_glyph_cachels_as_clean (struct window *w);
845 void reset_glyph_cachels (struct window *w);
846 glyph_index get_glyph_cachel_index (struct window *w, Lisp_Object glyph);
847
848 #ifdef MEMORY_USAGE_STATS
849 int compute_glyph_cachel_usage (glyph_cachel_dynarr *glyph_cachels,
850                                 struct overhead_stats *ovstats);
851 #endif /* MEMORY_USAGE_STATS */
852
853 /************************************************************************/
854 /*                              Display Tables                          */
855 /************************************************************************/
856
857 Lisp_Object display_table_entry (Emchar, Lisp_Object, Lisp_Object);
858 void get_display_tables (struct window *, face_index,
859                          Lisp_Object *, Lisp_Object *);
860
861 /****************************************************************************
862  *                            Subwindow Object                              *
863  ****************************************************************************/
864
865 /* redisplay needs a per-frame cache of subwindows being displayed so
866  * that we known when to unmap them */
867 typedef struct subwindow_cachel subwindow_cachel;
868 struct subwindow_cachel
869 {
870   Lisp_Object subwindow;
871   int x, y;
872   int width, height;
873   unsigned int being_displayed : 1;
874   unsigned int updated : 1;
875 };
876
877 typedef struct
878 {
879   Dynarr_declare (subwindow_cachel);
880 } subwindow_cachel_dynarr;
881
882 void mark_subwindow_cachels (subwindow_cachel_dynarr *elements);
883 void mark_subwindow_cachels_as_not_updated (struct frame *f);
884 void reset_subwindow_cachels (struct frame *f);
885 void unmap_subwindow (Lisp_Object subwindow);
886 void map_subwindow (Lisp_Object subwindow, int x, int y,
887                     struct display_glyph_area *dga);
888 void update_frame_subwindows (struct frame *f);
889 int find_matching_subwindow (struct frame* f, int x, int y, int width, int height);
890
891 struct expose_ignore
892 {
893   int   x;
894   int   y;
895   int   width;
896   int   height;
897   struct expose_ignore *next;
898 };
899
900 int check_for_ignored_expose (struct frame* f, int x, int y, int width, int height);
901 extern int hold_ignored_expose_registration;
902
903 #endif /* _XEMACS_GLYPHS_H_ */