872
+ − 1 /* Copyright (c) 1994, 1995 Free Software Foundation.
+ − 2 Copyright (c) 1995, 1996, 2002 Ben Wing.
+ − 3
+ − 4 This file is part of XEmacs.
+ − 5
+ − 6 XEmacs is free software; you can redistribute it and/or modify it
+ − 7 under the terms of the GNU General Public License as published by the
+ − 8 Free Software Foundation; either version 2, or (at your option) any
+ − 9 later version.
+ − 10
+ − 11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 14 for more details.
+ − 15
+ − 16 You should have received a copy of the GNU General Public License
+ − 17 along with XEmacs; see the file COPYING. If not, write to
+ − 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 19 Boston, MA 02111-1307, USA. */
+ − 20
+ − 21 /* Synched up with: Not in FSF. */
+ − 22
+ − 23 #ifndef INCLUDED_extents_impl_h_
+ − 24 #define INCLUDED_extents_impl_h_
+ − 25
+ − 26 #include "extents.h"
+ − 27
+ − 28 struct extent
+ − 29 {
+ − 30 struct lrecord_header lheader;
+ − 31
+ − 32 Memxpos start;
+ − 33 Memxpos end;
+ − 34 Lisp_Object object; /* A buffer, string, Qnil (extent detached from no
+ − 35 buffer), Qt (destroyed extent) */
+ − 36
+ − 37 /* Extent properties are conceptually a plist, but the most common
+ − 38 props are implemented as bits instead of conses. */
+ − 39 struct
+ − 40 {
+ − 41 Lisp_Object face;
+ − 42
+ − 43 /* These flags are simply an optimization for common boolean properties
+ − 44 which go onto the extent's property list. Any of them would work if
+ − 45 done in the normal way, but the space savings of doing these in this
+ − 46 way is significant. Note that if you add a flag, there are numerous
+ − 47 places in extents.c that need to know about it.
+ − 48
+ − 49 Another consideration is that some of these properties are accessed
+ − 50 during redisplay, so it's good for access to them to be fast (a bit
+ − 51 reference instead of a search down a plist).
+ − 52
+ − 53 `begin_glyph_layout' and `end_glyph_layout' are unusual in that
+ − 54 they have 4 states instead of 2.
+ − 55
+ − 56 Other special extent properties are stored in an auxiliary
+ − 57 structure that sits at the beginning of the plist. The has_aux
+ − 58 flag indicates whether this structure exists. The has_parent
+ − 59 flag is an optimization indicating whether the extent has a parent
+ − 60 (this could also be determined by looking in the aux structure). */
+ − 61
+ − 62 enum_field (glyph_layout) begin_glyph_layout :2;
+ − 63 /* 2 text, margins, or whitespace */
+ − 64 enum_field (glyph_layout) end_glyph_layout :2;
+ − 65 /* 4 text, margins, or whitespace */
+ − 66 unsigned int has_parent :1; /* 5 extent has a parent */
+ − 67 unsigned int has_aux :1; /* 6 extent has an aux. structure */
+ − 68 unsigned int start_open :1; /* 7 insertion behavior at start */
+ − 69 unsigned int end_open :1; /* 8 insertion behavior at end */
+ − 70 unsigned int unique :1; /* 9 there may be only one attached */
+ − 71 unsigned int duplicable :1; /* 10 copied to strings by kill/undo */
+ − 72 unsigned int detachable :1; /* 11 extent detaches if text deleted */
+ − 73 unsigned int internal :1; /* 12 used by map-extents etc. */
+ − 74 unsigned int in_red_event :1; /* 13 An event has been spawned for
+ − 75 initial redisplay.
+ − 76 (not exported to lisp) */
+ − 77 unsigned int unused16 :1; /* 16 unused bits */
+ − 78 /* --- Adding more flags will cause the extent struct to grow by another
+ − 79 word. It's not clear that this would make a difference, however,
+ − 80 because on 32-bit machines things tend to get allocated in chunks
+ − 81 of 4 bytes. */
+ − 82 } flags;
+ − 83 /* The plist may have an auxiliary structure as its first element */
+ − 84 Lisp_Object plist;
+ − 85 };
+ − 86
+ − 87 /* Basic properties of an extent (not affected by the extent's parent) */
+ − 88 #define extent_object(e) ((e)->object)
+ − 89 #define extent_start(e) ((e)->start + 0)
+ − 90 #define extent_end(e) ((e)->end + 0)
+ − 91 #define set_extent_start(e, val) ((void) ((e)->start = (val)))
+ − 92 #define set_extent_end(e, val) ((void) ((e)->end = (val)))
+ − 93 #define extent_endpoint(e, endp) ((endp) ? extent_end (e) : extent_start (e))
+ − 94 #define set_extent_endpoint(e, val, endp) \
+ − 95 ((endp) ? set_extent_end (e, val) : set_extent_start (e, val))
+ − 96 #define extent_detached_p(e) (extent_start (e) < 0)
+ − 97
+ − 98 /* Additional information that may be present in an extent. The idea is
+ − 99 that fast access is provided to this information, but since (hopefully)
+ − 100 most extents won't have this set on them, we usually don't need to
+ − 101 have this structure around and thus the size of an extent is smaller. */
+ − 102
+ − 103 typedef struct extent_auxiliary extent_auxiliary;
+ − 104 struct extent_auxiliary
+ − 105 {
3017
+ − 106 struct LCRECORD_HEADER header;
872
+ − 107
+ − 108 Lisp_Object begin_glyph;
+ − 109 Lisp_Object end_glyph;
+ − 110 Lisp_Object parent;
+ − 111 /* We use a weak list here. Originally I didn't do this and
+ − 112 depended on having the extent's finalization method remove
+ − 113 itself from its parent's children list. This runs into
+ − 114 lots and lots of problems though because everything is in
+ − 115 a really really bizarre state when an extent's finalization
+ − 116 method is called (it happens in sweep_extents() by way of
+ − 117 ADDITIONAL_FREE_extent()) and it's extremely difficult to
+ − 118 avoid getting hosed by just-freed objects. */
+ − 119 Lisp_Object children;
+ − 120 Lisp_Object invisible;
+ − 121 Lisp_Object read_only;
+ − 122 Lisp_Object mouse_face;
+ − 123 Lisp_Object initial_redisplay_function;
+ − 124 Lisp_Object before_change_functions, after_change_functions;
+ − 125 int priority;
+ − 126 };
+ − 127
+ − 128 extern struct extent_auxiliary extent_auxiliary_defaults;
+ − 129
+ − 130 struct extent_info
+ − 131 {
3017
+ − 132 struct LCRECORD_HEADER header;
872
+ − 133
+ − 134 struct extent_list *extents;
+ − 135 struct stack_of_extents *soe;
+ − 136 };
+ − 137
+ − 138 /* A "normal" field is one that is stored in the `struct flags' structure
+ − 139 in an extent. an "aux" field is one that is stored in the extent's
+ − 140 auxiliary structure.
+ − 141
+ − 142 The functions below that have `extent_no_chase' in their name operate
+ − 143 on an extent directly (ignoring its parent), and should normally
+ − 144 only be used on extents known not to have a parent. The other
+ − 145 versions chase down any parent links. */
+ − 146
+ − 147 #define extent_no_chase_normal_field(e, field) ((e)->flags.field)
+ − 148
+ − 149 DECLARE_INLINE_HEADER (
+ − 150 struct extent_auxiliary *
+ − 151 extent_aux_or_default (EXTENT e)
+ − 152 )
+ − 153 {
+ − 154 return e->flags.has_aux ?
+ − 155 XEXTENT_AUXILIARY (XCAR (e->plist)) :
+ − 156 & extent_auxiliary_defaults;
+ − 157 }
+ − 158
+ − 159 #define extent_no_chase_aux_field(e, field) (extent_aux_or_default(e)->field)
+ − 160
+ − 161 #define extent_normal_field(e, field) \
+ − 162 extent_no_chase_normal_field (extent_ancestor (e), field)
+ − 163
+ − 164 #define extent_aux_field(e, field) \
+ − 165 extent_no_chase_aux_field (extent_ancestor (e), field)
+ − 166
+ − 167 #define set_extent_no_chase_aux_field(e, field, value) do { \
+ − 168 EXTENT sencaf_e = (e); \
+ − 169 if (! sencaf_e->flags.has_aux) \
+ − 170 allocate_extent_auxiliary (sencaf_e); \
+ − 171 XEXTENT_AUXILIARY (XCAR (sencaf_e->plist))->field = (value);\
+ − 172 } while (0)
+ − 173
+ − 174 #define set_extent_no_chase_normal_field(e, field, value) \
+ − 175 extent_no_chase_normal_field (e, field) = (value)
+ − 176
+ − 177 #define set_extent_aux_field(e, field, value) \
+ − 178 set_extent_no_chase_aux_field (extent_ancestor (e), field, value)
+ − 179
+ − 180 #define set_extent_normal_field(e, field, value) \
+ − 181 set_extent_no_chase_normal_field (extent_ancestor (e), field, value)
+ − 182
+ − 183 /* The `parent' and `children' fields are not affected by any
+ − 184 parent links. We don't provide any settors for these fields
+ − 185 because they need special handling and it's cleaner just to
+ − 186 do this in the particular functions that need to do this. */
+ − 187
+ − 188 #define extent_parent(e) extent_no_chase_aux_field (e, parent)
+ − 189 #define extent_children(e) extent_no_chase_aux_field (e, children)
+ − 190
+ − 191 EXTENT extent_ancestor_1 (EXTENT e);
+ − 192
+ − 193 /* extent_ancestor() chases all the parent links until there aren't any
+ − 194 more. extent_ancestor_1() does the same thing but it a function;
+ − 195 the following optimizes the most common case. */
+ − 196 DECLARE_INLINE_HEADER (
+ − 197 EXTENT
+ − 198 extent_ancestor (EXTENT e)
+ − 199 )
+ − 200 {
+ − 201 return e->flags.has_parent ? extent_ancestor_1 (e) : e;
+ − 202 }
+ − 203
+ − 204 #define extent_begin_glyph(e) extent_aux_field (e, begin_glyph)
+ − 205 #define extent_end_glyph(e) extent_aux_field (e, end_glyph)
+ − 206 #define extent_priority(e) extent_aux_field (e, priority)
+ − 207 #define extent_invisible(e) extent_aux_field (e, invisible)
+ − 208 #define extent_read_only(e) extent_aux_field (e, read_only)
+ − 209 #define extent_mouse_face(e) extent_aux_field (e, mouse_face)
+ − 210 #define extent_initial_redisplay_function(e) extent_aux_field (e, initial_redisplay_function)
+ − 211 #define extent_before_change_functions(e) extent_aux_field (e, before_change_functions)
+ − 212 #define extent_after_change_functions(e) extent_aux_field (e, after_change_functions)
+ − 213
+ − 214 #define set_extent_begin_glyph(e, value) \
+ − 215 set_extent_aux_field (e, begin_glyph, value)
+ − 216 #define set_extent_end_glyph(e, value) \
+ − 217 set_extent_aux_field (e, end_glyph, value)
+ − 218 #define set_extent_priority(e, value) \
+ − 219 set_extent_aux_field (e, priority, value)
+ − 220 #define set_extent_invisible_1(e, value) \
+ − 221 set_extent_aux_field (e, invisible, value)
+ − 222 #define set_extent_read_only(e, value) \
+ − 223 set_extent_aux_field (e, read_only, value)
+ − 224 #define set_extent_mouse_face(e, value) \
+ − 225 set_extent_aux_field (e, mouse_face, value)
+ − 226 /* Use Fset_extent_initial_redisplay_function unless you know what you're doing */
+ − 227 #define set_extent_initial_redisplay_function(e, value) \
+ − 228 set_extent_aux_field (e, initial_redisplay_function, value)
+ − 229 #define set_extent_before_change_functions(e, value) \
+ − 230 set_extent_aux_field (e, before_change_functions, value)
+ − 231 #define set_extent_after_change_functions(e, value) \
+ − 232 set_extent_aux_field (e, after_change_functions, value)
+ − 233
+ − 234 #define extent_face(e) extent_normal_field (e, face)
+ − 235 #define extent_begin_glyph_layout(e) ((enum glyph_layout) extent_normal_field (e, begin_glyph_layout))
+ − 236 #define extent_end_glyph_layout(e) ((enum glyph_layout) extent_normal_field (e, end_glyph_layout))
+ − 237 #define extent_start_open_p(e) extent_normal_field (e, start_open)
+ − 238 #define extent_end_open_p(e) extent_normal_field (e, end_open)
+ − 239 #define extent_unique_p(e) extent_normal_field (e, unique)
+ − 240 #define extent_duplicable_p(e) extent_normal_field (e, duplicable)
+ − 241 #define extent_detachable_p(e) extent_normal_field (e, detachable)
+ − 242 #define extent_internal_p(e) extent_normal_field (e, internal)
+ − 243 #define extent_in_red_event_p(e) extent_normal_field (e, in_red_event)
+ − 244
+ − 245 #define set_extent_face(e, val) \
+ − 246 set_extent_normal_field (e, face, val)
+ − 247 #define set_extent_begin_glyph_layout(e, val) \
+ − 248 set_extent_normal_field (e, begin_glyph_layout, val)
+ − 249 #define set_extent_end_glyph_layout(e, val) \
+ − 250 set_extent_normal_field (e, end_glyph_layout, val)
+ − 251 #define set_extent_start_open_p(e, val) \
+ − 252 set_extent_normal_field (e, start_open, val)
+ − 253 #define set_extent_end_open_p(e, val) \
+ − 254 set_extent_normal_field (e, end_open, val)
+ − 255 #define set_extent_unique_p(e, val) \
+ − 256 set_extent_normal_field (e, unique, val)
+ − 257 #define set_extent_duplicable_p(e, val) \
+ − 258 set_extent_normal_field (e, duplicable, val)
+ − 259 #define set_extent_detachable_p(e, val) \
+ − 260 set_extent_normal_field (e, detachable, val)
+ − 261 #define set_extent_internal_p(e, val) \
+ − 262 set_extent_normal_field (e, internal, val)
+ − 263 #define set_extent_in_red_event_p(e, val) \
+ − 264 set_extent_normal_field (e, in_red_event, val)
+ − 265
+ − 266 DECLARE_INLINE_HEADER (
+ − 267 Lisp_Object *
+ − 268 extent_no_chase_plist_addr (EXTENT e)
+ − 269 )
+ − 270 {
+ − 271 return e->flags.has_aux ? &XCDR (e->plist) : &e->plist;
+ − 272 }
+ − 273
+ − 274 #define extent_no_chase_plist(e) (*extent_no_chase_plist_addr (e))
+ − 275
+ − 276 #define extent_plist_addr(e) extent_no_chase_plist_addr (extent_ancestor (e))
+ − 277 #define extent_plist_slot(e) extent_no_chase_plist (extent_ancestor (e))
+ − 278
+ − 279
+ − 280 #define EXTENT_LIVE_P(e) (!EQ (extent_object (e), Qt))
+ − 281
+ − 282 #define CHECK_LIVE_EXTENT(x) do { \
+ − 283 CHECK_EXTENT (x); \
+ − 284 if (!EXTENT_LIVE_P (XEXTENT (x))) \
+ − 285 dead_wrong_type_argument (Qextent_live_p, (x)); \
+ − 286 } while (0)
+ − 287 #define CONCHECK_LIVE_EXTENT(x) do { \
+ − 288 CONCHECK_EXTENT (x); \
+ − 289 if (!EXTENT_LIVE_P (XEXTENT (x))) \
+ − 290 x = wrong_type_argument (Qextent_live_p, (x)); \
+ − 291 } while (0)
+ − 292
+ − 293 #endif /* INCLUDED_extents_impl_h_ */