aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gdbinit16
-rw-r--r--src/ChangeLog777
-rw-r--r--src/ChangeLog.62
-rw-r--r--src/ChangeLog.92
-rw-r--r--src/Makefile.in14
-rw-r--r--src/alloc.c7
-rw-r--r--src/bidi.c1012
-rw-r--r--src/buffer.c154
-rw-r--r--src/buffer.h4
-rw-r--r--src/callint.c9
-rw-r--r--src/callproc.c6
-rw-r--r--src/character.c3
-rw-r--r--src/character.h39
-rw-r--r--src/chartab.c583
-rw-r--r--src/cm.c3
-rw-r--r--src/coding.c2
-rw-r--r--src/composite.c7
-rw-r--r--src/data.c3
-rw-r--r--src/dispextern.h50
-rw-r--r--src/dispnew.c6
-rw-r--r--src/editfns.c28
-rw-r--r--src/emacs.c7
-rw-r--r--src/eval.c50
-rw-r--r--src/fileio.c4
-rw-r--r--src/floatfns.c3
-rw-r--r--src/fns.c11
-rw-r--r--src/font.c34
-rw-r--r--src/gnutls.c55
-rw-r--r--src/gtkutil.c24
-rw-r--r--src/image.c4
-rw-r--r--src/indent.c20
-rw-r--r--src/intervals.c24
-rw-r--r--src/keyboard.c20
-rw-r--r--src/keymap.c553
-rw-r--r--src/keymap.h4
-rw-r--r--src/lread.c12
-rw-r--r--src/m/iris4d.h26
-rw-r--r--src/nsfns.m12
-rw-r--r--src/nsgui.h5
-rw-r--r--src/nsimage.m4
-rw-r--r--src/nsmenu.m3
-rw-r--r--src/nsselect.m8
-rw-r--r--src/nsterm.h41
-rw-r--r--src/nsterm.m65
-rw-r--r--src/process.c12
-rw-r--r--src/ralloc.c2
-rw-r--r--src/regex.c17
-rw-r--r--src/s/irix6-5.h7
-rw-r--r--src/search.c16
-rw-r--r--src/sysdep.c20
-rw-r--r--src/term.c53
-rw-r--r--src/termcap.c50
-rw-r--r--src/textprop.c10
-rw-r--r--src/tparam.c5
-rw-r--r--src/unexhp9k800.c172
-rw-r--r--src/w32.c8
-rw-r--r--src/w32fns.c13
-rw-r--r--src/widget.c6
-rw-r--r--src/window.c90
-rw-r--r--src/window.h4
-rw-r--r--src/xdisp.c1274
-rw-r--r--src/xfaces.c22
-rw-r--r--src/xfns.c11
-rw-r--r--src/xgselect.c10
-rw-r--r--src/xmenu.c11
-rw-r--r--src/xrdb.c23
-rw-r--r--src/xselect.c11
-rw-r--r--src/xsettings.c419
68 files changed, 4240 insertions, 1742 deletions
diff --git a/src/.gdbinit b/src/.gdbinit
index 2cf5663df91..0f51a00ea76 100644
--- a/src/.gdbinit
+++ b/src/.gdbinit
@@ -677,7 +677,7 @@ end
677 677
678define xvectype 678define xvectype
679 xgetptr $ 679 xgetptr $
680 set $size = ((struct Lisp_Vector *) $ptr)->size 680 set $size = ((struct Lisp_Vector *) $ptr)->header.size
681 output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag 681 output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag
682 echo \n 682 echo \n
683end 683end
@@ -818,7 +818,7 @@ end
818define xvector 818define xvector
819 xgetptr $ 819 xgetptr $
820 print (struct Lisp_Vector *) $ptr 820 print (struct Lisp_Vector *) $ptr
821 output ($->size > 50) ? 0 : ($->contents[0])@($->size & ~gdb_array_mark_flag) 821 output ($->header.size > 50) ? 0 : ($->contents[0])@($->header.size & ~gdb_array_mark_flag)
822echo \n 822echo \n
823end 823end
824document xvector 824document xvector
@@ -853,7 +853,7 @@ end
853define xcompiled 853define xcompiled
854 xgetptr $ 854 xgetptr $
855 print (struct Lisp_Vector *) $ptr 855 print (struct Lisp_Vector *) $ptr
856 output ($->contents[0])@($->size & 0xff) 856 output ($->contents[0])@($->header.size & 0xff)
857end 857end
858document xcompiled 858document xcompiled
859Print $ as a compiled function pointer. 859Print $ as a compiled function pointer.
@@ -903,7 +903,7 @@ define xchartable
903 print (struct Lisp_Char_Table *) $ptr 903 print (struct Lisp_Char_Table *) $ptr
904 printf "Purpose: " 904 printf "Purpose: "
905 xprintsym $->purpose 905 xprintsym $->purpose
906 printf " %d extra slots", ($->size & 0x1ff) - 68 906 printf " %d extra slots", ($->header.size & 0x1ff) - 68
907 echo \n 907 echo \n
908end 908end
909document xchartable 909document xchartable
@@ -927,7 +927,7 @@ end
927define xboolvector 927define xboolvector
928 xgetptr $ 928 xgetptr $
929 print (struct Lisp_Bool_Vector *) $ptr 929 print (struct Lisp_Bool_Vector *) $ptr
930 output ($->size > 256) ? 0 : ($->data[0])@((($->size & ~gdb_array_mark_flag) + 7)/ 8) 930 output ($->header.size > 256) ? 0 : ($->data[0])@((($->header.size & ~gdb_array_mark_flag) + 7)/ 8)
931 echo \n 931 echo \n
932end 932end
933document xboolvector 933document xboolvector
@@ -1093,7 +1093,7 @@ define xpr
1093# end 1093# end
1094 end 1094 end
1095 if $type == Lisp_Vectorlike 1095 if $type == Lisp_Vectorlike
1096 set $size = ((struct Lisp_Vector *) $ptr)->size 1096 set $size = ((struct Lisp_Vector *) $ptr)->header.size
1097 if ($size & PVEC_FLAG) 1097 if ($size & PVEC_FLAG)
1098 set $vec = (enum pvec_type) ($size & PVEC_TYPE_MASK) 1098 set $vec = (enum pvec_type) ($size & PVEC_TYPE_MASK)
1099 if $vec == PVEC_NORMAL_VECTOR 1099 if $vec == PVEC_NORMAL_VECTOR
@@ -1202,7 +1202,7 @@ end
1202 1202
1203define xfont 1203define xfont
1204 xgetptr $ 1204 xgetptr $
1205 set $size = (((struct Lisp_Vector *) $ptr)->size & 0x1FF) 1205 set $size = (((struct Lisp_Vector *) $ptr)->header.size & 0x1FF)
1206 if $size == FONT_SPEC_MAX 1206 if $size == FONT_SPEC_MAX
1207 print (struct font_spec *) $ptr 1207 print (struct font_spec *) $ptr
1208 else 1208 else
@@ -1229,7 +1229,7 @@ define xbacktrace
1229 printf "0x%x ", $ptr 1229 printf "0x%x ", $ptr
1230 if $type == Lisp_Vectorlike 1230 if $type == Lisp_Vectorlike
1231 xgetptr (*$bt->function) 1231 xgetptr (*$bt->function)
1232 set $size = ((struct Lisp_Vector *) $ptr)->size 1232 set $size = ((struct Lisp_Vector *) $ptr)->header.size
1233 output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag 1233 output ($size & PVEC_FLAG) ? (enum pvec_type) ($size & PVEC_TYPE_MASK) : $size & ~gdb_array_mark_flag
1234 else 1234 else
1235 printf "Lisp type %d", $type 1235 printf "Lisp type %d", $type
diff --git a/src/ChangeLog b/src/ChangeLog
index 1e537f3872e..21563806ece 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,764 @@
12011-07-14 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix minor problems found by static checking.
4 * bidi.c (bidi_cache_size): Now EMACS_INT, not size_t.
5 (elsz): Now a signed constant, not a size_t var. We prefer signed
6 types to unsigned, to avoid integer comparison confusion. Without
7 this change, GCC 4.6.1 with -Wunsafe-loop-optimizations complains
8 "cannot optimize loop, the loop counter may overflow", a symptom
9 of the confusion.
10 * indent.c (Fvertical_motion): Mark locals as initialized.
11 * xdisp.c (reseat_to_string): Fix pointer signedness issue.
12
132011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
14
15 * search.c (Fre_search_backward): Mention `case-fold-search' in
16 all the re_search_* functions (bug#8138).
17
18 * keyboard.c (Fopen_dribble_file): Document when the file is
19 closed (bug#8056).
20
212011-07-14 Eli Zaretskii <eliz@gnu.org>
22
23 * bidi.c (bidi_dump_cached_states): Fix format of displaying
24 bidi_cache_idx.
25
26 Support bidi reordering of display and overlay strings.
27 * xdisp.c (compute_display_string_pos)
28 (compute_display_string_end): Accept additional argument STRING.
29 (init_iterator, reseat_1): Initialize bidi_it->string.s to NULL.
30 (reseat_to_string): Initialize bidi_it->string.s and
31 bidi_it->string.schars.
32 (Fcurrent_bidi_paragraph_direction): Initialize itb.string.s to
33 NULL (avoids a crash in bidi_paragraph_init). Initialize
34 itb.string.lstring.
35 (init_iterator): Call bidi_init_it only of a valid
36 buffer position was specified. Initialize paragraph_embedding to
37 L2R.
38 (reseat_to_string): Initialize the bidi iterator.
39 (display_string): If we need to ignore text properties of
40 LISP_STRING, set IT->stop_charpos to IT->end_charpos. (The
41 original value of -1 will not work with bidi.)
42 (compute_display_string_pos): First arg is now struct
43 `text_pos *'; all callers changed. Support display properties on
44 Lisp strings.
45 (compute_display_string_end): Support display properties on Lisp
46 strings.
47 (init_iterator, reseat_1, reseat_to_string): Initialize the
48 string.bufpos member to 0 (zero, for compatibility with IT_CHARPOS
49 when iterating on a string not from display properties).
50 (compute_display_string_pos, compute_display_string_end): Fix
51 calculation of the object to scan. Fixes an error when using
52 arrow keys.
53 (next_element_from_buffer): Don't abort when IT_CHARPOS is before
54 base_level_stop; instead, set base_level_stop to BEGV. Fixes
55 crashes in vertical-motion.
56 (next_element_from_buffer): Improve commentary for when
57 the iterator is before prev_stop.
58 (init_iterator): Initialize bidi_p from the default value of
59 bidi-display-reordering, not from buffer-local value. Use the
60 buffer-local value only if initializing for buffer iteration.
61 (handle_invisible_prop): Support invisible properties on strings
62 that are being bidi-reordered.
63 (set_iterator_to_next): Support bidi reordering of C strings and
64 Lisp strings.
65 (next_element_from_string): Support bidi reordering of Lisp
66 strings.
67 (handle_stop_backwards): Support Lisp strings as well.
68 (display_string): Support display of R2L glyph rows. Use
69 IT_STRING_CHARPOS when displaying from a Lisp string.
70 (init_iterator): Don't initialize it->bidi_p for strings
71 here.
72 (reseat_to_string): Initialize it->bidi_p for strings here.
73 (next_element_from_string, next_element_from_c_string)
74 (next_element_from_buffer): Add xassert's for correspondence
75 between IT's object being iterated and it->bidi_it.string
76 structure.
77 (face_before_or_after_it_pos): Support bidi iteration.
78 (next_element_from_c_string): Handle the case of the first string
79 character that is not the first one in the visual order.
80 (get_visually_first_element): New function, refactored from common
81 parts of next_element_from_buffer, next_element_from_string, and
82 next_element_from_c_string.
83 (tool_bar_lines_needed, redisplay_tool_bar)
84 (display_menu_bar): Force left-to-right direction. Add a FIXME
85 comment for making that be controlled by a user option.
86 (push_it, pop_it): Save and restore the state of the
87 bidi iterator. Save and restore the bidi_p flag.
88 (pop_it): Iterate out of display property for string iteration as
89 well.
90 (iterate_out_of_display_property): Support iteration over strings.
91 (handle_single_display_spec): Set up it->bidi_it for iteration
92 over a display string, and call bidi_init_it.
93 (handle_single_display_spec, next_overlay_string)
94 (get_overlay_strings_1, push_display_prop): Set up the bidi
95 iterator for displaying display or overlay strings.
96 (forward_to_next_line_start): Don't use the shortcut if
97 bidi-iterating.
98 (back_to_previous_visible_line_start): If handle_display_prop
99 pushed the iterator stack, restore the internal state of the bidi
100 iterator by calling bidi_pop_it same number of times.
101 (reseat_at_next_visible_line_start): If ON_NEWLINE_P is non-zero,
102 and we are bidi-iterating, don't decrement the iterator position;
103 instead, set the first_elt flag in the bidi iterator, to produce
104 the same effect.
105 (reseat_1): Remove redundant setting of string_from_display_prop_p.
106 (push_display_prop): xassert that we are iterating a buffer.
107 (push_it, pop_it): Save and restore paragraph_embedding member.
108 (handle_single_display_spec, next_overlay_string)
109 (get_overlay_strings_1, reseat_1, reseat_to_string)
110 (push_display_prop): Set up the `unibyte' member of bidi_it.string
111 correctly. Don't assume unibyte strings are not bidi-reordered.
112 (compute_display_string_pos)
113 (compute_display_string_end): Fix handling the case of C string.
114 (push_it, pop_it): Save and restore from_disp_prop_p.
115 (handle_single_display_spec, push_display_prop): Set the
116 from_disp_prop_p flag.
117 (get_overlay_strings_1): Reset the from_disp_prop_p flag.
118 (pop_it): Call iterate_out_of_display_property only if we are
119 popping after iteration over a string that came from a display
120 property. Fix a typo in popping stretch info. Add an assertion
121 for verifying that the iterator position is in sync with the bidi
122 iterator.
123 (handle_single_display_spec, get_overlay_strings_1)
124 (push_display_prop): Fix initialization of paragraph direction for
125 string when that of the parent object is not yet determined.
126 (reseat_1): Call bidi_init_it to resync the bidi
127 iterator with IT's position. (Bug#7616)
128 (find_row_edges): If ROW->start.pos gives position
129 smaller than min_pos, use it as ROW->minpos. (Bug#7616)
130 (handle_stop, back_to_previous_visible_line_start, reseat_1):
131 Reset the from_disp_prop_p flag.
132 (SAVE_IT, RESTORE_IT): New macros.
133 (pos_visible_p, face_before_or_after_it_pos)
134 (back_to_previous_visible_line_start)
135 (move_it_in_display_line_to, move_it_in_display_line)
136 (move_it_to, move_it_vertically_backward, move_it_by_lines)
137 (try_scrolling, redisplay_window, display_line): Use them when
138 saving a temporary copy of the iterator and restoring it back.
139 (back_to_previous_visible_line_start, reseat_1)
140 (init_iterator): Empty the bidi cache "stack".
141 (move_it_in_display_line_to): If iterator ended up at
142 EOL, but we never saw any buffer positions smaller than
143 to_charpos, return MOVE_POS_MATCH_OR_ZV. Fixes vertical cursor
144 motion in bidi-reordered lines.
145 (move_it_in_display_line_to): Record prev_method and prev_pos
146 immediately before the call to set_iterator_to_next. Fixes cursor
147 motion in bidi-reordered lines with stretch glyphs and strings
148 displayed in margins. (Bug#8133) (Bug#8867)
149 Return MOVE_POS_MATCH_OR_ZV only if iterator position is past
150 TO_CHARPOS.
151 (pos_visible_p): Support positions in bidi-reordered lines. Save
152 and restore bidi cache.
153
154 * bidi.c (bidi_level_of_next_char): clen should be EMACS_NT, not int.
155 (bidi_paragraph_info): Delete unused struct.
156 (bidi_cache_idx, bidi_cache_last_idx): Declare EMACS_INT.
157 (bidi_cache_start): New variable.
158 (bidi_cache_reset): Reset bidi_cache_idx to bidi_cache_start, not
159 to zero.
160 (bidi_cache_fetch_state, bidi_cache_search)
161 (bidi_cache_find_level_change, bidi_cache_iterator_state)
162 (bidi_cache_find, bidi_peek_at_next_level)
163 (bidi_level_of_next_char, bidi_find_other_level_edge)
164 (bidi_move_to_visually_next): Compare cache index with
165 bidi_cache_start rather than with zero.
166 (bidi_fetch_char): Accept new argument STRING; all callers
167 changed. Support iteration over a string. Support strings with
168 display properties. Support unibyte strings. Fix the type of
169 `len' according to what STRING_CHAR_AND_LENGTH expects.
170 (bidi_paragraph_init, bidi_resolve_explicit_1)
171 (bidi_resolve_explicit, bidi_resolve_weak)
172 (bidi_level_of_next_char, bidi_move_to_visually_next): Support
173 iteration over a string.
174 (bidi_set_sor_type, bidi_resolve_explicit_1)
175 (bidi_resolve_explicit, bidi_type_of_next_char): ignore_bn_limit
176 can now be zero (for strings); special values 0 and -1 were
177 changed to -1 and -2, respectively.
178 (bidi_char_at_pos): New function.
179 (bidi_paragraph_init, bidi_resolve_explicit, bidi_resolve_weak):
180 Call it instead of FETCH_MULTIBYTE_CHAR.
181 (bidi_move_to_visually_next): Abort if charpos or bytepos were not
182 initialized to valid values.
183 (bidi_init_it): Don't initialize charpos and bytepos with invalid
184 values.
185 (bidi_level_of_next_char): Allow the sentinel "position" to pass
186 the test for valid cached positions. Fix the logic for looking up
187 the sentinel state in the cache. GCPRO the Lisp string we are
188 iterating.
189 (bidi_push_it, bidi_pop_it): New functions.
190 (bidi_initialize): Initialize the bidi cache start stack pointer.
191 (bidi_cache_ensure_space): New function, refactored from part of
192 bidi_cache_iterator_state. Don't assume the required size is just
193 one BIDI_CACHE_CHUNK away.
194 (bidi_cache_start_stack, bidi_push_it): Use IT_STACK_SIZE.
195 (bidi_count_bytes, bidi_char_at_pos): New functions.
196 (bidi_cache_search): Don't assume bidi_cache_last_idx is
197 always valid if bidi_cache_idx is valid.
198 (bidi_cache_find_level_change): xassert that bidi_cache_last_idx
199 is valid if it's going to be used.
200 (bidi_shelve_cache, bidi_unshelve_cache): New functions.
201 (bidi_cache_fetch_state, bidi_cache_search)
202 (bidi_cache_find_level_change, bidi_cache_ensure_space)
203 (bidi_cache_iterator_state, bidi_cache_find)
204 (bidi_find_other_level_edge, bidi_cache_start_stack): All
205 variables related to cache indices are now EMACS_INT.
206
207 * dispextern.h (struct bidi_string_data): New structure.
208 (struct bidi_it): New member `string'. Make flag members be 1-bit
209 fields, and put them last in the struct.
210 (compute_display_string_pos, compute_display_string_end): Update
211 prototypes.
212 (bidi_push_it, bidi_pop_it): Add prototypes.
213 (struct iterator_stack_entry): New members bidi_p,
214 paragraph_embedding, and from_disp_prop_p.
215 (struct it): Member bidi_p is now a bit field 1 bit wide.
216 (bidi_shelve_cache, bidi_unshelve_cache): Declare
217 prototypes.
218
219 * .gdbinit (xvectype, xvector, xcompiled, xchartable, xboolvector)
220 (xpr, xfont, xbacktrace): Use "header.size" when accessing vectors
221 and vector-like objects.
222
223 * dispnew.c (buffer_posn_from_coords): Save and restore the bidi
224 cache around display iteration.
225
226 * window.c (Fwindow_end, window_scroll_pixel_based)
227 (displayed_window_lines, Frecenter): Save and restore the bidi
228 cache around display iteration.
229
2302011-07-14 Lars Magne Ingebrigtsen <larsi@gnus.org>
231
232 * editfns.c (Fdelete_region): Clarify the use of the named
233 parameters (bug#6788).
234
2352011-07-14 Martin Rudalics <rudalics@gmx.at>
236
237 * indent.c (Fvertical_motion): Set and restore w->pointm when
238 saving and restoring the window's buffer (Bug#9006).
239
2402011-07-13 Lars Magne Ingebrigtsen <larsi@gnus.org>
241
242 * editfns.c (Fstring_to_char): Clarify just what is returned
243 (bug#6576). Text by Eli Zaretskii.
244
2452011-07-13 Juanma Barranquero <lekktu@gmail.com>
246
247 * gnutls.c (init_gnutls_functions): Honor gnutls_log_level (bug#9059).
248
2492011-07-13 Eli Zaretskii <eliz@gnu.org>
250
251 * buffer.c (mmap_find): Fix a typo.
252
2532011-07-13 Johan Bockgård <bojohan@gnu.org>
254
255 Fix execution of x selection hooks.
256 * xselect.c (Qx_lost_selection_functions)
257 (Qx_sent_selection_functions): New vars.
258 (syms_of_xselect): DEFSYM them.
259 (x_handle_selection_request): Pass Qx_sent_selection_functions
260 rather than Vx_sent_selection_functions to Frun_hook_with_args.
261 (x_handle_selection_clear,x_clear_frame_selections):
262 Pass Qx_lost_selection_functions rather than
263 Vx_lost_selection_functions to Frun_hook_with_args.
264
2652011-07-13 Paul Eggert <eggert@cs.ucla.edu>
266
267 * buffer.c (Fget_buffer_create): Initialize inhibit_shrinking.
268 The old code sometimes used this field without initializing it.
269
270 * alloc.c (gc_sweep): Don't read past end of array.
271 In theory, the old code could also have corrupted Emacs internals,
272 though it'd be very unlikely.
273
2742011-07-12 Andreas Schwab <schwab@linux-m68k.org>
275
276 * character.c (Fcharacterp): Don't advertise optional ignored
277 argument. (Bug#4026)
278
2792011-07-12 Lars Magne Ingebrigtsen <larsi@gnus.org>
280
281 * keymap.c (syms_of_keymap): Clarify that "modifier" is "modifier
282 key" (bug#4257).
283
284 * window.c (Fset_window_start): Doc fix (bug#4199).
285 (Fset_window_hscroll): Ditto.
286
2872011-07-12 Paul Eggert <eggert@cs.ucla.edu>
288
289 Fix minor new problems caught by GCC 4.6.1.
290 * term.c (init_tty): Remove unused local.
291 * xsettings.c (store_monospaced_changed): Define this function only
292 if (defined HAVE_GSETTINGS || defined HAVE_GCONF), as it's
293 not used otherwise.
294
2952011-07-12 Chong Yidong <cyd@stupidchicken.com>
296
297 * xdisp.c (Vresize_mini_windows): Minor doc fix (Bug#3300).
298
2992011-07-11 Lars Magne Ingebrigtsen <larsi@gnus.org>
300
301 * xdisp.c (syms_of_xdisp): Make it explicit that the mini-windows
302 are the mini-buffer and the echo area (bug#3320).
303
304 * term.c (init_tty): Remove support for supdup, c10 and perq
305 terminals, which are no longer supported (bug#1482).
306
3072011-07-10 Johan Bockgård <bojohan@gnu.org>
308
309 * xdisp.c (Ftool_bar_lines_needed): Fix WINDOWP check.
310
3112011-07-10 Jan Djärv <jan.h.d@swipnet.se>
312
313 * xmenu.c (menu_highlight_callback): Only pass frame to show_help_event
314 for non-popups (Bug#3642).
315
3162011-07-10 Andreas Schwab <schwab@linux-m68k.org>
317
318 * alloc.c (reset_malloc_hooks): Protoize.
319 * buffer.c (mmap_init, mmap_find, mmap_free_1, mmap_enlarge)
320 (mmap_set_vars, mmap_alloc, mmap_free, mmap_realloc): Likewise.
321 * cm.c (losecursor): Likewise.
322 * data.c (fmod): Likewise.
323 * dispnew.c (swap_glyphs_in_rows): Likewise.
324 * emacs.c (memory_warning_signal): Likewise.
325 * floatfns.c (float_error): Likewise.
326 * font.c (check_gstring, check_otf_features, otf_tag_symbol)
327 (otf_open, font_otf_capability, generate_otf_features)
328 (font_otf_DeviceTable, font_otf_ValueRecord, font_otf_Anchor):
329 Likewise.
330 * image.c (pbm_read_file): Likewise.
331 * indent.c (string_display_width): Likewise.
332 * intervals.c (check_for_interval, search_for_interval)
333 (inc_interval_count, count_intervals, root_interval)
334 (adjust_intervals_for_insertion, make_new_interval): Likewise.
335 * lread.c (defalias): Likewise.
336 * ralloc.c (r_alloc_check): Likewise.
337 * regex.c (set_image_of_range_1, set_image_of_range)
338 (regex_grow_registers): Likewise.
339 * sysdep.c (strerror): Likewise.
340 * termcap.c (valid_filename_p, tprint, main): Likewise.
341 * tparam.c (main): Likewise.
342 * unexhp9k800.c (run_time_remap, save_data_space)
343 (update_file_ptrs, read_header, write_header, calculate_checksum)
344 (copy_file, copy_rest, display_header): Likewise.
345 * widget.c (mark_shell_size_user_specified, create_frame_gcs):
346 Likewise.
347 * xdisp.c (check_it): Likewise.
348 * xfaces.c (register_color, unregister_color, unregister_colors):
349 Likewise.
350 * xfns.c (print_fontset_result): Likewise.
351 * xrdb.c (member, fatal, main): Likewise.
352
3532011-07-10 Paul Eggert <eggert@cs.ucla.edu>
354
355 Fix minor problems found by static checking (Bug#9031).
356 * chartab.c (char_table_set_range, map_sub_char_table):
357 Remove unused locals.
358 (uniprop_table): Now static.
359 * composite.c (_work_char): Remove unused static var.
360
3612011-07-09 Juanma Barranquero <lekktu@gmail.com>
362
363 * chartab.c (uniprop_table_uncompress): Remove unused local variable.
364
3652011-07-09 Jan Djärv <jan.h.d@swipnet.se>
366
367 * gtkutil.c (qttip_cb): Remove code without function.
368
3692011-07-09 Eli Zaretskii <eliz@gnu.org>
370
371 * w32.c (pthread_sigmask): New stub.
372
3732011-07-08 Paul Eggert <eggert@cs.ucla.edu>
374
375 Use pthread_sigmask, not sigprocmask (Bug#9010).
376 sigprocmask is portable only for single-threaded applications, and
377 Emacs can be multi-threaded when it uses GTK.
378 * Makefile.in (LIB_PTHREAD_SIGMASK): New macro.
379 (LIBES): Use it.
380 * callproc.c (Fcall_process):
381 * process.c (create_process):
382 * sysdep.c (sys_sigblock, sys_sigunblock, sys_sigsetmask):
383 Use pthread_sigmask, not sigprocmask.
384
3852011-07-08 Jan Djärv <jan.h.d@swipnet.se>
386
387 * gtkutil.c (qttip_cb): Set line wrap to FALSE for tooltip widget.
388 (xg_prepare_tooltip): Revert text in x->ttip_lbl, margins was
389 wrong (Bug#8591).
390
3912011-07-08 Jan Djärv <jan.h.d@swipnet.se>
392
393 * gtkutil.c (xg_prepare_tooltip): Fix indentation and comment.
394 Put text in x->ttip_lbl instead of gtk_tooltip_set_text (Bug#8591).
395 (xg_hide_tooltip): Fix comment.
396
397 * nsterm.m (initFrameFromEmacs): Don't use ns_return_types
398 in registerServicesMenuSendTypes.
399 (validRequestorForSendType): Don't check ns_return_types.
400
401 * nsfns.m (Fx_open_connection): Put NSStringPboardType into
402 ns_return_type.
403
4042011-07-08 Jason Rumney <jasonr@gnu.org>
405
406 * w32fns.c (w32_wnd_proc) [WM_TIMER, WM_SET_CURSOR]: Avoid using
407 frame struct members of non-existent frames (Bug#6284).
408
4092011-07-08 Jan Djärv <jan.h.d@swipnet.se>
410
411 * nsterm.m (keyDown): Call to wantsToDelayTextChangeNotifications and
412 variable firstTime not needed on OSX >= 10.6.
413 (setPosition): setFloatValue:knobProportion: is deprecated on OSX
414 >= 10.5. Use setKnobProportion, setDoubleValue.
415
416 * nsterm.h (MAC_OS_X_VERSION_10_3, MAC_OS_X_VERSION_10_4)
417 (MAC_OS_X_VERSION_10_5): Define if not defined.
418 (EmacsView, EmacsTooltip): Implements NSWindowDelegate on OSX >= 10.6.
419 (EmacsMenu): Implements NSMenuDelegate on OSX >= 10.6.
420 (EmacsToolbar): Implements NSToolbarDelegate on OSX >= 10.6.
421
422 * nsselect.m (ns_string_from_pasteboard): Don't use deprecated methods
423 cString and lossyCString on OSX >= 10.4
424
425 * nsmenu.m (fillWithWidgetValue): Don't use depercated method
426 sizeToFit on OSX >= 10.2.
427
428 * nsimage.m (allocInitFromFile): Don't use deprecated method
429 bestRepresentationForDevice on OSX >= 10.6.
430
431 * nsfns.m (check_ns_display_info): Cast to long and use %ld in error
432 to avoid warning.
433
434 * emacs.c: Declare unexec_init_emacs_zone.
435
436 * nsgui.h: Fix compiler warning about gnulib redefining verify.
437
438 * nsselect.m (ns_get_local_selection): Change to extern (Bug#8842).
439
440 * nsmenu.m (ns_update_menubar): Remove useless setDelegate call
441 on svcsMenu (Bug#8842).
442
443 * nsfns.m (Fx_open_connection): Remove NSStringPboardType from
444 ns_return_types.
445 (Fns_list_services): Just return Qnil on 10.6, code not working there.
446
447 * nsterm.m (QUTF8_STRING): Declare.
448 (initFrameFromEmacs): Call registerServicesMenuSendTypes.
449 (validRequestorForSendType): Return type is (id).
450 Change indexOfObjectIdenticalTo to indexOfObject.
451 Check if we have local selection before returning self (Bug#8842).
452 (writeSelectionToPasteboard): Put local selection into paste board
453 if we have a local selection (Bug#8842).
454 (syms_of_nsterm): DEFSYM QUTF8_STRING.
455
456 * nsterm.h (MAC_OS_X_VERSION_10_6): Define here instead of nsterm.m.
457 (ns_get_local_selection): Declare.
458
4592011-07-07 Lars Magne Ingebrigtsen <larsi@gnus.org>
460
461 * keymap.c (describe_map_tree): Don't insert a double newline at
462 the end of the buffer (bug#1169) and return whether we inserted
463 something.
464
465 * callint.c (Fcall_interactively): Change "reading args" to
466 "providing args" to try to clarify what it does (bug#1010).
467
4682011-07-07 Kenichi Handa <handa@m17n.org>
469
470 * composite.c (composition_compute_stop_pos): Ignore a static
471 composition starting before CHARPOS (Bug#8915).
472
473 * xdisp.c (handle_composition_prop): Likewise.
474
4752011-07-07 Eli Zaretskii <eliz@gnu.org>
476
477 * term.c (produce_glyphs) <xassert>: Allow IT_GLYPHLESS in it->what.
478 (Bug#9015)
479
4802011-07-07 Kenichi Handa <handa@m17n.org>
481
482 * character.h (unicode_category_t): New enum type.
483
484 * chartab.c (uniprop_decoder_t, uniprop_encoder_t): New types.
485 (Qchar_code_property_table): New variable.
486 (UNIPROP_TABLE_P, UNIPROP_GET_DECODER)
487 (UNIPROP_COMPRESSED_FORM_P): New macros.
488 (char_table_ascii): Uncompress the compressed values.
489 (sub_char_table_ref): New arg is_uniprop. Callers changed.
490 Uncompress the compressed values.
491 (sub_char_table_ref_and_range): Likewise.
492 (char_table_ref_and_range): Uncompress the compressed values.
493 (sub_char_table_set): New arg is_uniprop. Callers changed.
494 Uncompress the compressed values.
495 (sub_char_table_set_range): Args changed. Callers changed.
496 (char_table_set_range): Adjuted for the above change.
497 (map_sub_char_table): Delete args default_val and parent. Add arg
498 top. Give decoded values to a Lisp function.
499 (map_char_table): Adjusted for the above change. Give decoded
500 values to a Lisp function. Gcpro more variables.
501 (uniprop_table_uncompress)
502 (uniprop_decode_value_run_length): New functions.
503 (uniprop_decoder, uniprop_decoder_count): New variables.
504 (uniprop_get_decoder, uniprop_encode_value_character)
505 (uniprop_encode_value_run_length, uniprop_encode_value_numeric):
506 New functions.
507 (uniprop_encoder, uniprop_encoder_count): New variables.
508 (uniprop_get_encoder, uniprop_table)
509 (Funicode_property_table_internal, Fget_unicode_property_internal)
510 (Fput_unicode_property_internal): New functions.
511 (syms_of_chartab): DEFSYM Qchar_code_property_table, defsubr
512 Sunicode_property_table_internal, Sget_unicode_property_internal,
513 and Sput_unicode_property_internal. Defvar_lisp
514 char-code-property-alist.
515
516 * composite.c (CHAR_COMPOSABLE_P): Adjusted for the change of
517 Vunicode_category_table.
518
519 * font.c (font_range): Adjusted for the change of
520 Vunicode_category_table.
521
5222011-07-07 Dan Nicolaescu <dann@ics.uci.edu>
523
524 * m/iris4d.h: Remove file, move contents ...
525 * s/irix6-5.h: ... here.
526
5272011-07-06 Paul Eggert <eggert@cs.ucla.edu>
528
529 Remove unportable assumption about struct layout (Bug#8884).
530 * alloc.c (mark_buffer):
531 * buffer.c (reset_buffer_local_variables, Fbuffer_local_variables)
532 (clone_per_buffer_values): Don't assume that
533 sizeof (struct buffer) is a multiple of sizeof (Lisp_Object).
534 This isn't true in general, and it's particularly not true
535 if Emacs is configured with --with-wide-int.
536 * buffer.h (FIRST_FIELD_PER_BUFFER, LAST_FIELD_PER_BUFFER):
537 New macros, used in the buffer.c change.
538
5392011-07-05 Jan Djärv <jan.h.d@swipnet.se>
540
541 * xsettings.c: Use both GConf and GSettings if both are available.
542 (store_config_changed_event): Add comment.
543 (dpyinfo_valid, store_font_name_changed, map_tool_bar_style)
544 (store_tool_bar_style_changed): New functions.
545 (store_monospaced_changed): Add comment. Call dpyinfo_valid.
546 (struct xsettings): Move font inside HAVE_XFT.
547 (GSETTINGS_TOOL_BAR_STYLE, GSETTINGS_FONT_NAME): New defines.
548 (GSETTINGS_MONO_FONT): Renamed from SYSTEM_MONO_FONT.
549 Move inside HAVE_XFT.
550 (something_changed_gsettingsCB): Renamed from something_changedCB.
551 Check for changes in GSETTINGS_TOOL_BAR_STYLE and GSETTINGS_FONT_NAME
552 also.
553 (GCONF_TOOL_BAR_STYLE, GCONF_FONT_NAME): New defines.
554 (GCONF_MONO_FONT): Renamed from SYSTEM_MONO_FONT. Move inside HAVE_XFT.
555 (something_changed_gconfCB): Renamed from something_changedCB.
556 Check for changes in GCONF_TOOL_BAR_STYLE and GCONF_FONT_NAME also.
557 (parse_settings): Move check for font inside HAVE_XFT.
558 (read_settings, apply_xft_settings): Add comment.
559 (read_and_apply_settings): Add comment. Call map_tool_bar_style and
560 store_tool_bar_style_changed. Move check for font inside HAVE_XFT and
561 call store_font_name_changed.
562 (xft_settings_event): Add comment.
563 (init_gsettings): Add comment. Get values for GSETTINGS_TOOL_BAR_STYLE
564 and GSETTINGS_FONT_NAME. Move check for fonts within HAVE_XFT.
565 (init_gconf): Add comment. Get values for GCONF_TOOL_BAR_STYLE
566 and GCONF_FONT_NAME. Move check for fonts within HAVE_XFT.
567 (xsettings_initialize): Call init_gsettings last.
568 (xsettings_get_system_font, xsettings_get_system_normal_font): Add
569 comment.
570
5712011-07-05 Paul Eggert <eggert@cs.ucla.edu>
572
573 Random fixes. E.g., (random) never returned negative values.
574 * fns.c (Frandom): Use GET_EMACS_TIME for random seed, and add the
575 subseconds part to the entropy, as that's a bit more random.
576 Prefer signed to unsigned, since the signedness doesn't matter and
577 in general we prefer signed. When given a limit, use a
578 denominator equal to INTMASK + 1, not to VALMASK + 1, because the
579 latter isn't right if USE_2_TAGS_FOR_INTS.
580 * sysdep.c (get_random): Return a value in the range 0..INTMASK,
581 not 0..VALMASK. Don't discard "excess" bits that random () returns.
582
5832011-07-04 Stefan Monnier <monnier@iro.umontreal.ca>
584
585 * textprop.c (text_property_stickiness):
586 Obey Vtext_property_default_nonsticky.
587 (syms_of_textprop): Add `display' to Vtext_property_default_nonsticky.
588 * w32fns.c (syms_of_w32fns):
589 * xfns.c (syms_of_xfns): Don't Add `display' since it's there by default.
590
5912011-07-04 Paul Eggert <eggert@cs.ucla.edu>
592
593 * fileio.c (barf_or_query_if_file_exists): Use S_ISDIR.
594 This is more efficient than Ffile_directory_p and avoids a minor race.
595
5962011-07-04 Lars Magne Ingebrigtsen <larsi@gnus.org>
597
598 * buffer.c (Foverlay_put): Say what the return value is
599 (bug#7835).
600
601 * fileio.c (barf_or_query_if_file_exists): Check first if the file
602 is a directory before asking whether to use the file name
603 (bug#7564).
604 (barf_or_query_if_file_exists): Make the "File is a directory"
605 error be more correct.
606
607 * fns.c (Frequire): Remove the mention of the .gz files, since
608 that's installation-specific, but keep the mention of
609 `get-load-suffixes'.
610
6112011-07-04 Paul Eggert <eggert@cs.ucla.edu>
612
613 * editfns.c (Fformat_time_string): Don't assume strlen fits in int.
614 Report string overflow if the output is too long.
615
6162011-07-04 Juanma Barranquero <lekktu@gmail.com>
617
618 * gnutls.c (Fgnutls_boot): Don't mention :verify-error.
619 (syms_of_gnutls): Remove duplicate DEFSYM for
620 Qgnutls_bootprop_verify_hostname_error, an error for
621 Qgnutls_bootprop_verify_error (which is no longer used).
622
623 * eval.c (find_handler_clause): Remove parameters `sig' and `data',
624 unused since 2011-01-26T20:02:07Z!monnier@iro.umontreal.ca. All callers changed.
625 Also (re)move comments that are misplaced or no longer relevant.
626
6272011-07-03 Lars Magne Ingebrigtsen <larsi@gnus.org>
628
629 * callint.c (Finteractive): Clarify the meaning of "@" (bug#8813).
630
6312011-07-03 Chong Yidong <cyd@stupidchicken.com>
632
633 * xfaces.c (Finternal_merge_in_global_face): Modify the foreground
634 and background color parameters if they have been changed.
635
6362011-07-03 Lars Magne Ingebrigtsen <larsi@gnus.org>
637
638 * editfns.c (Fformat): Clarify the - and 0 flags (bug#6659).
639
6402011-07-03 Paul Eggert <eggert@cs.ucla.edu>
641
642 * xsettings.c (SYSTEM_FONT): Define only when used.
643 No need to define when HAVE_GSETTINGS || !HAVE_XFT.
644
645 * keymap.c (access_keymap_1): Now static.
646
6472011-07-02 Chong Yidong <cyd@stupidchicken.com>
648
649 * keyboard.c (command_loop_1): If a down-mouse event is unbound,
650 leave any prefix arg for the up event (Bug#1586).
651
6522011-07-02 Lars Magne Ingebrigtsen <larsi@gnus.org>
653
654 * lread.c (syms_of_lread): Mention single symbols defined by
655 `defvar' or `defconst' (bug#7154).
656
657 * fns.c (Frequire): Mention .el.gz files (bug#7314).
658 (Frequire): Mention get-load-suffixes.
659
6602011-07-02 Martin Rudalics <rudalics@gmx.at>
661
662 * window.h (window): Remove clone_number slot.
663 * window.c (Fwindow_clone_number, Fset_window_clone_number):
664 Remove.
665 (make_parent_window, make_window, saved_window)
666 (Fset_window_configuration, save_window_save): Don't deal with
667 clone numbers.
668 * buffer.c (Qclone_number): Remove declaration.
669 (sort_overlays, overlay_strings): Don't deal with clone numbers.
670
6712011-07-02 Stefan Monnier <monnier@iro.umontreal.ca>
672
673 Add multiple inheritance to keymaps.
674 * keymap.c (Fmake_composed_keymap): New function.
675 (Fset_keymap_parent): Simplify.
676 (fix_submap_inheritance): Remove.
677 (access_keymap_1): New function extracted from access_keymap to handle
678 embedded parents and handle lists of maps.
679 (access_keymap): Use it.
680 (Fkeymap_prompt, map_keymap_internal, map_keymap, store_in_keymap)
681 (Fcopy_keymap): Handle embedded parents.
682 (Fcommand_remapping, define_as_prefix): Simplify.
683 (Fkey_binding): Simplify.
684 (syms_of_keymap): Move minibuffer-local-completion-map,
685 minibuffer-local-filename-completion-map,
686 minibuffer-local-must-match-map, and
687 minibuffer-local-filename-must-match-map to Elisp.
688 (syms_of_keymap): Defsubr make-composed-keymap.
689 * keyboard.c (menu_bar_items): Use map_keymap_canonical.
690 (parse_menu_item): Trivial simplification.
691
6922011-07-01 Glenn Morris <rgm@gnu.org>
693
694 * Makefile.in (SETTINGS_LIBS): Fix typo.
695
6962011-07-01 Kazuhiro Ito <kzhr@d1.dion.ne.jp> (tiny patch)
697
698 * coding.c (Fencode_coding_string): Record the last coding system
699 used, as the function doc string says (bug#8738).
700
7012011-07-01 Jan Djärv <jan.h.d@swipnet.se>
702
703 * xsettings.c (store_monospaced_changed): Take new font as arg and
704 check for change against current_mono_font.
705 (EMACS_TYPE_SETTINGS): Remove this and related defines.
706 (emacs_settings_constructor, emacs_settings_get_property)
707 (emacs_settings_set_property, emacs_settings_class_init)
708 (emacs_settings_init, gsettings_obj): Remove.
709 (something_changedCB): New function for HAVE_GSETTINGS.
710 (something_changedCB): HAVE_GCONF: Call store_monospaced_changed
711 with value as argument.
712 (init_gsettings): Check that GSETTINGS_SCHEMA exists before calling
713 g_settings_new (Bug#8967). Do not create gsettings_obj.
714 Remove calls to g_settings_bind. Connect something_changedCB to
715 "changed".
716
717 * xgselect.c: Add defined (HAVE_GSETTINGS).
718 (xgselect_initialize): Ditto.
719
720 * process.c: Add defined (HAVE_GSETTINGS) for xgselect.h
721 (wait_reading_process_output): Add defined (HAVE_GSETTINGS) for
722 xg_select.
723
7242011-07-01 Paul Eggert <eggert@cs.ucla.edu>
725
726 * eval.c (struct backtrace): Simplify and port the data structure.
727 Do not assume that "int nargs : BITS_PER_INT - 2;" produces a
728 signed bit field, as this assumption is not portable and it makes
729 Emacs crash when compiled with Sun C 5.8 on sparc. Do not use
730 "char debug_on_exit : 1" as this is not portable either; instead,
731 use the portable "unsigned int debug_on_exit : 1". Remove unused
732 member evalargs. Remove obsolete comments about cc bombing out.
733
7342011-06-30 Jan Djärv <jan.h.d@swipnet.se>
735
736 * xsettings.c: Include glib-object.h, gio/gio.h if HAVE_GSETTINGS.
737 Let HAVE_GSETTINGS override HAVE_GCONF.
738 (store_monospaced_changed): New function.
739 (EMACS_SETTINGS): A new type derived from GObject to handle
740 GSettings notifications.
741 (emacs_settings_constructor, emacs_settings_get_property)
742 (emacs_settings_set_property, emacs_settings_class_init):
743 New functions.
744 (gsettings_client, gsettings_obj): New variables.
745 (GSETTINGS_SCHEMA): New define.
746 (something_changedCB): Call store_monospaced_changed.
747 (init_gsettings): New function.
748 (xsettings_initialize): Call init_gsettings.
749 (syms_of_xsettings): Initialize gsettings_client, gsettings_obj
750 to NULL.
751
752 * Makefile.in (SETTINGS_CFLAGS, SETTINGS_LIBS): Renamed from
753 GCONF_CFLAGS/LIBS.
754
7552011-06-29 Martin Rudalics <rudalics@gmx.at>
756
757 * window.c (resize_root_window, grow_mini_window)
758 (shrink_mini_window): Rename Qresize_root_window to
759 Qwindow_resize_root_window and Qresize_root_window_vertically to
760 Qwindow_resize_root_window_vertically.
761
12011-06-28 Paul Eggert <eggert@cs.ucla.edu> 7622011-06-28 Paul Eggert <eggert@cs.ucla.edu>
2 763
3 * gnutls.c (Qgnutls_bootprop_verify_error): Remove unused var. 764 * gnutls.c (Qgnutls_bootprop_verify_error): Remove unused var.
@@ -47,8 +808,8 @@
47 min_width/height (Bug#8919). 808 min_width/height (Bug#8919).
48 809
49 * gtkutil.c (xg_create_frame_widgets): Pass f to emacs_fixed_new. 810 * gtkutil.c (xg_create_frame_widgets): Pass f to emacs_fixed_new.
50 (x_wm_set_size_hint): Remove call to emacs_fixed_set_min_size. Fix 811 (x_wm_set_size_hint): Remove call to emacs_fixed_set_min_size.
51 indentation. 812 Fix indentation.
52 813
532011-06-26 Eli Zaretskii <eliz@gnu.org> 8142011-06-26 Eli Zaretskii <eliz@gnu.org>
54 815
@@ -1405,7 +2166,7 @@
1405 (xpm_put_color_table_h): 2166 (xpm_put_color_table_h):
1406 * lisp.h (struct Lisp_Hash_Table): 2167 * lisp.h (struct Lisp_Hash_Table):
1407 * minibuf.c (Ftry_completion, Fall_completions, Ftest_completion): 2168 * minibuf.c (Ftry_completion, Fall_completions, Ftest_completion):
1408 * print.c (print): Use 'EMACS_UINT' and 'EMACS_INT' 2169 * print.c (print): Use 'EMACS_UINT' and 'EMACS_INT'
1409 for hashes and hash indexes, instead of 'unsigned' and 'int'. 2170 for hashes and hash indexes, instead of 'unsigned' and 'int'.
1410 * alloc.c (allocate_vectorlike): 2171 * alloc.c (allocate_vectorlike):
1411 Check for overflow in vector size calculations. 2172 Check for overflow in vector size calculations.
@@ -1609,7 +2370,7 @@
1609 and %.0c. Fix bug with strchr succeeding on '\0' when looking for 2370 and %.0c. Fix bug with strchr succeeding on '\0' when looking for
1610 flags. Fix bug with (format "%c" 256.0). Avoid integer overflow when 2371 flags. Fix bug with (format "%c" 256.0). Avoid integer overflow when
1611 formatting out-of-range floating point numbers with int 2372 formatting out-of-range floating point numbers with int
1612 formats. (Bug#8668) 2373 formats. (Bug#8668)
1613 2374
1614 * lisp.h (FIXNUM_OVERFLOW_P): Work even if arg is a NaN. 2375 * lisp.h (FIXNUM_OVERFLOW_P): Work even if arg is a NaN.
1615 2376
@@ -1702,7 +2463,7 @@
1702 2463
1703 * dispnew.c (shift_glyph_matrix, scrolling_window): Mark scrolled row 2464 * dispnew.c (shift_glyph_matrix, scrolling_window): Mark scrolled row
1704 for fringe update if it has periodic bitmap. 2465 for fringe update if it has periodic bitmap.
1705 (row_equal_p): Also compare left_fringe_offset, right_fringe_offset, 2466 (row_equal_p): Also compare left_fringe_offset, right_fringe_offset,
1706 and fringe_bitmap_periodic_p. 2467 and fringe_bitmap_periodic_p.
1707 2468
1708 * fringe.c (get_fringe_bitmap_data): New function. 2469 * fringe.c (get_fringe_bitmap_data): New function.
@@ -2573,9 +3334,9 @@
2573 :verify-hostname-error, :verify-error, and :verify-flags 3334 :verify-hostname-error, :verify-error, and :verify-flags
2574 parameters of `gnutls-boot' and documented those parameters in the 3335 parameters of `gnutls-boot' and documented those parameters in the
2575 docstring. Start callback support. 3336 docstring. Start callback support.
2576 (emacs_gnutls_handshake): Add Woe32 support. Retry handshake 3337 (emacs_gnutls_handshake): Add Woe32 support. Retry handshake
2577 unless a fatal error occured. Call gnutls_alert_send_appropriate 3338 unless a fatal error occurred. Call gnutls_alert_send_appropriate
2578 on error. Return error code. 3339 on error. Return error code.
2579 (emacs_gnutls_write): Call emacs_gnutls_handle_error. 3340 (emacs_gnutls_write): Call emacs_gnutls_handle_error.
2580 (emacs_gnutls_read): Likewise. 3341 (emacs_gnutls_read): Likewise.
2581 (Fgnutls_boot): Return handshake error code. 3342 (Fgnutls_boot): Return handshake error code.
diff --git a/src/ChangeLog.6 b/src/ChangeLog.6
index d7903568102..f9372aa666a 100644
--- a/src/ChangeLog.6
+++ b/src/ChangeLog.6
@@ -4599,7 +4599,7 @@
4599 4599
46001995-08-14 Erik Naggum <erik@naggum.no> 46001995-08-14 Erik Naggum <erik@naggum.no>
4601 4601
4602 * emacs.c (standard_args): Add option --eval to evalute an 4602 * emacs.c (standard_args): Add option --eval to evaluate an
4603 expression on the command line and print the result. 4603 expression on the command line and print the result.
4604 4604
46051995-08-14 Richard Stallman <rms@mole.gnu.ai.mit.edu> 46051995-08-14 Richard Stallman <rms@mole.gnu.ai.mit.edu>
diff --git a/src/ChangeLog.9 b/src/ChangeLog.9
index 0c39de74a6a..f25434087c1 100644
--- a/src/ChangeLog.9
+++ b/src/ChangeLog.9
@@ -5985,7 +5985,7 @@
5985 GC_PROTECT_MALLOC_STATE]: New function. 5985 GC_PROTECT_MALLOC_STATE]: New function.
5986 (PROTECT_MALLOC_STATE): New macro. 5986 (PROTECT_MALLOC_STATE): New macro.
5987 (__malloc_initialize, morecore, _malloc_internal) 5987 (__malloc_initialize, morecore, _malloc_internal)
5988 (_free_internal) _realloc_internal): Use it to make _heapinfo 5988 (_free_internal, _realloc_internal): Use it to make _heapinfo
5989 read-only outside of gmalloc. 5989 read-only outside of gmalloc.
5990 5990
5991 * keymap.c: Update copyright. 5991 * keymap.c: Update copyright.
diff --git a/src/Makefile.in b/src/Makefile.in
index d1e212e92b7..27ae6aff4da 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -152,8 +152,8 @@ DBUS_LIBS = @DBUS_LIBS@
152## dbusbind.o if HAVE_DBUS, else empty. 152## dbusbind.o if HAVE_DBUS, else empty.
153DBUS_OBJ = @DBUS_OBJ@ 153DBUS_OBJ = @DBUS_OBJ@
154 154
155GCONF_CFLAGS = @GCONF_CFLAGS@ 155SETTINGS_CFLAGS = @SETTINGS_CFLAGS@
156GCONF_LIBS = @GCONF_LIBS@ 156SETTINGS_LIBS = @SETTINGS_LIBS@
157 157
158## gtkutil.o if USE_GTK, else empty. 158## gtkutil.o if USE_GTK, else empty.
159GTK_OBJ=@GTK_OBJ@ 159GTK_OBJ=@GTK_OBJ@
@@ -275,6 +275,8 @@ LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
275LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ 275LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@
276LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ 276LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@
277 277
278LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
279
278INTERVALS_H = dispextern.h intervals.h composite.h 280INTERVALS_H = dispextern.h intervals.h composite.h
279 281
280GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ 282GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
@@ -311,8 +313,10 @@ ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I$(srcdir) \
311 $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \ 313 $(C_SWITCH_MACHINE) $(C_SWITCH_SYSTEM) $(C_SWITCH_X_SITE) \
312 $(C_SWITCH_X_SYSTEM) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ 314 $(C_SWITCH_X_SYSTEM) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
313 $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \ 315 $(LIBXML2_CFLAGS) $(DBUS_CFLAGS) \
316
314 $(WEBKIT_CFLAGS) $(CLUTTER_CFLAGS) \ 317 $(WEBKIT_CFLAGS) $(CLUTTER_CFLAGS) \
315 $(GCONF_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ 318 $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
319
316 $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \ 320 $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) $(PROFILING_CFLAGS) \
317 $(LIBGNUTLS_CFLAGS) \ 321 $(LIBGNUTLS_CFLAGS) \
318 $(C_WARNINGS_SWITCH) $(CFLAGS) 322 $(C_WARNINGS_SWITCH) $(CFLAGS)
@@ -391,9 +395,9 @@ LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
391 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \ 395 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \
392 $(WEBKIT_LIBS) $(CLUTTER_LIBS) \ 396 $(WEBKIT_LIBS) $(CLUTTER_LIBS) \
393 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 397 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
394 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(GCONF_LIBS) $(LIBSELINUX_LIBS) \ 398 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
395 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ 399 $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
396 $(LIBGNUTLS_LIBS) \ 400 $(LIBGNUTLS_LIBS) $(LIB_PTHREAD_SIGMASK) \
397 $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) 401 $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC)
398 402
399all: emacs$(EXEEXT) $(OTHER_FILES) 403all: emacs$(EXEEXT) $(OTHER_FILES)
diff --git a/src/alloc.c b/src/alloc.c
index 43befd722bb..44f935c243d 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1258,7 +1258,7 @@ emacs_blocked_realloc (void *ptr, size_t size, const void *ptr2)
1258 calls malloc because it is the first call, and we have an endless loop. */ 1258 calls malloc because it is the first call, and we have an endless loop. */
1259 1259
1260void 1260void
1261reset_malloc_hooks () 1261reset_malloc_hooks (void)
1262{ 1262{
1263 __free_hook = old_free_hook; 1263 __free_hook = old_free_hook;
1264 __malloc_hook = old_malloc_hook; 1264 __malloc_hook = old_malloc_hook;
@@ -5619,7 +5619,8 @@ mark_buffer (Lisp_Object buf)
5619 /* buffer-local Lisp variables start at `undo_list', 5619 /* buffer-local Lisp variables start at `undo_list',
5620 tho only the ones from `name' on are GC'd normally. */ 5620 tho only the ones from `name' on are GC'd normally. */
5621 for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); 5621 for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name);
5622 (char *)ptr < (char *)buffer + sizeof (struct buffer); 5622 ptr <= &PER_BUFFER_VALUE (buffer,
5623 PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER));
5623 ptr++) 5624 ptr++)
5624 mark_object (*ptr); 5625 mark_object (*ptr);
5625 5626
@@ -5732,7 +5733,7 @@ gc_sweep (void)
5732 int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT; 5733 int ilim = (lim + BITS_PER_INT - 1) / BITS_PER_INT;
5733 5734
5734 /* Scan the mark bits an int at a time. */ 5735 /* Scan the mark bits an int at a time. */
5735 for (i = 0; i <= ilim; i++) 5736 for (i = 0; i < ilim; i++)
5736 { 5737 {
5737 if (cblk->gcmarkbits[i] == -1) 5738 if (cblk->gcmarkbits[i] == -1)
5738 { 5739 {
diff --git a/src/bidi.c b/src/bidi.c
index 469afdb3819..c83ee549923 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1,4 +1,4 @@
1/* Low-level bidirectional buffer-scanning functions for GNU Emacs. 1/* Low-level bidirectional buffer/string-scanning functions for GNU Emacs.
2 Copyright (C) 2000-2001, 2004-2005, 2009-2011 2 Copyright (C) 2000-2001, 2004-2005, 2009-2011
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
@@ -20,7 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20/* Written by Eli Zaretskii <eliz@gnu.org>. 20/* Written by Eli Zaretskii <eliz@gnu.org>.
21 21
22 A sequential implementation of the Unicode Bidirectional algorithm, 22 A sequential implementation of the Unicode Bidirectional algorithm,
23 as per UAX#9, a part of the Unicode Standard. 23 (UBA) as per UAX#9, a part of the Unicode Standard.
24 24
25 Unlike the reference and most other implementations, this one is 25 Unlike the reference and most other implementations, this one is
26 designed to be called once for every character in the buffer or 26 designed to be called once for every character in the buffer or
@@ -35,11 +35,16 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35 details about its algorithm that finds the next visual-order 35 details about its algorithm that finds the next visual-order
36 character by resolving their levels on the fly. 36 character by resolving their levels on the fly.
37 37
38 The two other entry points are bidi_paragraph_init and 38 Two other entry points are bidi_paragraph_init and
39 bidi_mirror_char. The first determines the base direction of a 39 bidi_mirror_char. The first determines the base direction of a
40 paragraph, while the second returns the mirrored version of its 40 paragraph, while the second returns the mirrored version of its
41 argument character. 41 argument character.
42 42
43 A few auxiliary entry points are used to initialize the bidi
44 iterator for iterating an object (buffer or string), push and pop
45 the bidi iterator state, and save and restore the state of the bidi
46 cache.
47
43 If you want to understand the code, you will have to read it 48 If you want to understand the code, you will have to read it
44 together with the relevant portions of UAX#9. The comments include 49 together with the relevant portions of UAX#9. The comments include
45 references to UAX#9 rules, for that very reason. 50 references to UAX#9 rules, for that very reason.
@@ -66,16 +71,6 @@ static Lisp_Object bidi_type_table, bidi_mirror_table;
66#define RLM_CHAR 0x200F 71#define RLM_CHAR 0x200F
67#define BIDI_EOB -1 72#define BIDI_EOB -1
68 73
69/* Local data structures. (Look in dispextern.h for the rest.) */
70
71/* What we need to know about the current paragraph. */
72struct bidi_paragraph_info {
73 EMACS_INT start_bytepos; /* byte position where it begins */
74 EMACS_INT end_bytepos; /* byte position where it ends */
75 int embedding_level; /* its basic embedding level */
76 bidi_dir_t base_dir; /* its base direction */
77};
78
79/* Data type for describing the bidirectional character categories. */ 74/* Data type for describing the bidirectional character categories. */
80typedef enum { 75typedef enum {
81 UNKNOWN_BC, 76 UNKNOWN_BC,
@@ -90,43 +85,10 @@ int bidi_ignore_explicit_marks_for_paragraph_level = 1;
90static Lisp_Object paragraph_start_re, paragraph_separate_re; 85static Lisp_Object paragraph_start_re, paragraph_separate_re;
91static Lisp_Object Qparagraph_start, Qparagraph_separate; 86static Lisp_Object Qparagraph_start, Qparagraph_separate;
92 87
93static void 88
94bidi_initialize (void) 89/***********************************************************************
95{ 90 Utilities
96 91 ***********************************************************************/
97#include "biditype.h"
98#include "bidimirror.h"
99
100 int i;
101
102 bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L));
103 staticpro (&bidi_type_table);
104
105 for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++)
106 char_table_set_range (bidi_type_table, bidi_type[i].from, bidi_type[i].to,
107 make_number (bidi_type[i].type));
108
109 bidi_mirror_table = Fmake_char_table (Qnil, Qnil);
110 staticpro (&bidi_mirror_table);
111
112 for (i = 0; i < sizeof bidi_mirror / sizeof bidi_mirror[0]; i++)
113 char_table_set (bidi_mirror_table, bidi_mirror[i].from,
114 make_number (bidi_mirror[i].to));
115
116 Qparagraph_start = intern ("paragraph-start");
117 staticpro (&Qparagraph_start);
118 paragraph_start_re = Fsymbol_value (Qparagraph_start);
119 if (!STRINGP (paragraph_start_re))
120 paragraph_start_re = build_string ("\f\\|[ \t]*$");
121 staticpro (&paragraph_start_re);
122 Qparagraph_separate = intern ("paragraph-separate");
123 staticpro (&Qparagraph_separate);
124 paragraph_separate_re = Fsymbol_value (Qparagraph_separate);
125 if (!STRINGP (paragraph_separate_re))
126 paragraph_separate_re = build_string ("[ \t\f]*$");
127 staticpro (&paragraph_separate_re);
128 bidi_initialized = 1;
129}
130 92
131/* Return the bidi type of a character CH, subject to the current 93/* Return the bidi type of a character CH, subject to the current
132 directional OVERRIDE. */ 94 directional OVERRIDE. */
@@ -243,6 +205,77 @@ bidi_mirror_char (int c)
243 return c; 205 return c;
244} 206}
245 207
208/* Determine the start-of-run (sor) directional type given the two
209 embedding levels on either side of the run boundary. Also, update
210 the saved info about previously seen characters, since that info is
211 generally valid for a single level run. */
212static inline void
213bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after)
214{
215 int higher_level = level_before > level_after ? level_before : level_after;
216
217 /* The prev_was_pdf gork is required for when we have several PDFs
218 in a row. In that case, we want to compute the sor type for the
219 next level run only once: when we see the first PDF. That's
220 because the sor type depends only on the higher of the two levels
221 that we find on the two sides of the level boundary (see UAX#9,
222 clause X10), and so we don't need to know the final embedding
223 level to which we descend after processing all the PDFs. */
224 if (!bidi_it->prev_was_pdf || level_before < level_after)
225 /* FIXME: should the default sor direction be user selectable? */
226 bidi_it->sor = (higher_level & 1) != 0 ? R2L : L2R;
227 if (level_before > level_after)
228 bidi_it->prev_was_pdf = 1;
229
230 bidi_it->prev.type = UNKNOWN_BT;
231 bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 =
232 bidi_it->last_strong.orig_type = UNKNOWN_BT;
233 bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L;
234 bidi_it->prev_for_neutral.charpos = bidi_it->charpos;
235 bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos;
236 bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 =
237 bidi_it->next_for_neutral.orig_type = UNKNOWN_BT;
238 bidi_it->ignore_bn_limit = -1; /* meaning it's unknown */
239}
240
241/* Push the current embedding level and override status; reset the
242 current level to LEVEL and the current override status to OVERRIDE. */
243static inline void
244bidi_push_embedding_level (struct bidi_it *bidi_it,
245 int level, bidi_dir_t override)
246{
247 bidi_it->stack_idx++;
248 xassert (bidi_it->stack_idx < BIDI_MAXLEVEL);
249 bidi_it->level_stack[bidi_it->stack_idx].level = level;
250 bidi_it->level_stack[bidi_it->stack_idx].override = override;
251}
252
253/* Pop the embedding level and directional override status from the
254 stack, and return the new level. */
255static inline int
256bidi_pop_embedding_level (struct bidi_it *bidi_it)
257{
258 /* UAX#9 says to ignore invalid PDFs. */
259 if (bidi_it->stack_idx > 0)
260 bidi_it->stack_idx--;
261 return bidi_it->level_stack[bidi_it->stack_idx].level;
262}
263
264/* Record in SAVED_INFO the information about the current character. */
265static inline void
266bidi_remember_char (struct bidi_saved_info *saved_info,
267 struct bidi_it *bidi_it)
268{
269 saved_info->charpos = bidi_it->charpos;
270 saved_info->bytepos = bidi_it->bytepos;
271 saved_info->type = bidi_it->type;
272 bidi_check_type (bidi_it->type);
273 saved_info->type_after_w1 = bidi_it->type_after_w1;
274 bidi_check_type (bidi_it->type_after_w1);
275 saved_info->orig_type = bidi_it->orig_type;
276 bidi_check_type (bidi_it->orig_type);
277}
278
246/* Copy the bidi iterator from FROM to TO. To save cycles, this only 279/* Copy the bidi iterator from FROM to TO. To save cycles, this only
247 copies the part of the level stack that is actually in use. */ 280 copies the part of the level stack that is actually in use. */
248static inline void 281static inline void
@@ -259,22 +292,37 @@ bidi_copy_it (struct bidi_it *to, struct bidi_it *from)
259 to->level_stack[i] = from->level_stack[i]; 292 to->level_stack[i] = from->level_stack[i];
260} 293}
261 294
262/* Caching the bidi iterator states. */ 295
296/***********************************************************************
297 Caching the bidi iterator states
298 ***********************************************************************/
263 299
264#define BIDI_CACHE_CHUNK 200 300#define BIDI_CACHE_CHUNK 200
265static struct bidi_it *bidi_cache; 301static struct bidi_it *bidi_cache;
266static size_t bidi_cache_size = 0; 302static EMACS_INT bidi_cache_size = 0;
267static size_t elsz = sizeof (struct bidi_it); 303enum { elsz = sizeof (struct bidi_it) };
268static int bidi_cache_idx; /* next unused cache slot */ 304static EMACS_INT bidi_cache_idx; /* next unused cache slot */
269static int bidi_cache_last_idx; /* slot of last cache hit */ 305static EMACS_INT bidi_cache_last_idx; /* slot of last cache hit */
270 306static EMACS_INT bidi_cache_start = 0; /* start of cache for this
307 "stack" level */
308
309/* Reset the cache state to the empty state. We only reset the part
310 of the cache relevant to iteration of the current object. Previous
311 objects, which are pushed on the display iterator's stack, are left
312 intact. This is called when the cached information is no more
313 useful for the current iteration, e.g. when we were reseated to a
314 new position on the same object. */
271static inline void 315static inline void
272bidi_cache_reset (void) 316bidi_cache_reset (void)
273{ 317{
274 bidi_cache_idx = 0; 318 bidi_cache_idx = bidi_cache_start;
275 bidi_cache_last_idx = -1; 319 bidi_cache_last_idx = -1;
276} 320}
277 321
322/* Shrink the cache to its minimal size. Called when we init the bidi
323 iterator for reordering a buffer or a string that does not come
324 from display properties, because that means all the previously
325 cached info is of no further use. */
278static inline void 326static inline void
279bidi_cache_shrink (void) 327bidi_cache_shrink (void)
280{ 328{
@@ -288,11 +336,11 @@ bidi_cache_shrink (void)
288} 336}
289 337
290static inline void 338static inline void
291bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it) 339bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it)
292{ 340{
293 int current_scan_dir = bidi_it->scan_dir; 341 int current_scan_dir = bidi_it->scan_dir;
294 342
295 if (idx < 0 || idx >= bidi_cache_idx) 343 if (idx < bidi_cache_start || idx >= bidi_cache_idx)
296 abort (); 344 abort ();
297 345
298 bidi_copy_it (bidi_it, &bidi_cache[idx]); 346 bidi_copy_it (bidi_it, &bidi_cache[idx]);
@@ -304,13 +352,15 @@ bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it)
304 level less or equal to LEVEL. if LEVEL is -1, disregard the 352 level less or equal to LEVEL. if LEVEL is -1, disregard the
305 resolved levels in cached states. DIR, if non-zero, means search 353 resolved levels in cached states. DIR, if non-zero, means search
306 in that direction from the last cache hit. */ 354 in that direction from the last cache hit. */
307static inline int 355static inline EMACS_INT
308bidi_cache_search (EMACS_INT charpos, int level, int dir) 356bidi_cache_search (EMACS_INT charpos, int level, int dir)
309{ 357{
310 int i, i_start; 358 EMACS_INT i, i_start;
311 359
312 if (bidi_cache_idx) 360 if (bidi_cache_idx > bidi_cache_start)
313 { 361 {
362 if (bidi_cache_last_idx == -1)
363 bidi_cache_last_idx = bidi_cache_idx - 1;
314 if (charpos < bidi_cache[bidi_cache_last_idx].charpos) 364 if (charpos < bidi_cache[bidi_cache_last_idx].charpos)
315 { 365 {
316 dir = -1; 366 dir = -1;
@@ -333,7 +383,7 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir)
333 if (dir < 0) 383 if (dir < 0)
334 { 384 {
335 /* Linear search for now; FIXME! */ 385 /* Linear search for now; FIXME! */
336 for (i = i_start; i >= 0; i--) 386 for (i = i_start; i >= bidi_cache_start; i--)
337 if (bidi_cache[i].charpos <= charpos 387 if (bidi_cache[i].charpos <= charpos
338 && charpos < bidi_cache[i].charpos + bidi_cache[i].nchars 388 && charpos < bidi_cache[i].charpos + bidi_cache[i].nchars
339 && (level == -1 || bidi_cache[i].resolved_level <= level)) 389 && (level == -1 || bidi_cache[i].resolved_level <= level))
@@ -355,8 +405,9 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir)
355/* Find a cached state where the resolved level changes to a value 405/* Find a cached state where the resolved level changes to a value
356 that is lower than LEVEL, and return its cache slot index. DIR is 406 that is lower than LEVEL, and return its cache slot index. DIR is
357 the direction to search, starting with the last used cache slot. 407 the direction to search, starting with the last used cache slot.
358 BEFORE, if non-zero, means return the index of the slot that is 408 If DIR is zero, we search backwards from the last occupied cache
359 ``before'' the level change in the search direction. That is, 409 slot. BEFORE, if non-zero, means return the index of the slot that
410 is ``before'' the level change in the search direction. That is,
360 given the cached levels like this: 411 given the cached levels like this:
361 412
362 1122333442211 413 1122333442211
@@ -366,14 +417,16 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir)
366 C, searching backwards (DIR = -1) for LEVEL = 2 will return the 417 C, searching backwards (DIR = -1) for LEVEL = 2 will return the
367 index of slot B or A, depending whether BEFORE is, respectively, 418 index of slot B or A, depending whether BEFORE is, respectively,
368 non-zero or zero. */ 419 non-zero or zero. */
369static int 420static EMACS_INT
370bidi_cache_find_level_change (int level, int dir, int before) 421bidi_cache_find_level_change (int level, int dir, int before)
371{ 422{
372 if (bidi_cache_idx) 423 if (bidi_cache_idx)
373 { 424 {
374 int i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; 425 EMACS_INT i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
375 int incr = before ? 1 : 0; 426 int incr = before ? 1 : 0;
376 427
428 xassert (!dir || bidi_cache_last_idx >= 0);
429
377 if (!dir) 430 if (!dir)
378 dir = -1; 431 dir = -1;
379 else if (!incr) 432 else if (!incr)
@@ -381,7 +434,7 @@ bidi_cache_find_level_change (int level, int dir, int before)
381 434
382 if (dir < 0) 435 if (dir < 0)
383 { 436 {
384 while (i >= incr) 437 while (i >= bidi_cache_start + incr)
385 { 438 {
386 if (bidi_cache[i - incr].resolved_level >= 0 439 if (bidi_cache[i - incr].resolved_level >= 0
387 && bidi_cache[i - incr].resolved_level < level) 440 && bidi_cache[i - incr].resolved_level < level)
@@ -405,9 +458,22 @@ bidi_cache_find_level_change (int level, int dir, int before)
405} 458}
406 459
407static inline void 460static inline void
461bidi_cache_ensure_space (EMACS_INT idx)
462{
463 /* Enlarge the cache as needed. */
464 if (idx >= bidi_cache_size)
465 {
466 while (idx >= bidi_cache_size)
467 bidi_cache_size += BIDI_CACHE_CHUNK;
468 bidi_cache =
469 (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
470 }
471}
472
473static inline void
408bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) 474bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
409{ 475{
410 int idx; 476 EMACS_INT idx;
411 477
412 /* We should never cache on backward scans. */ 478 /* We should never cache on backward scans. */
413 if (bidi_it->scan_dir == -1) 479 if (bidi_it->scan_dir == -1)
@@ -417,23 +483,17 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
417 if (idx < 0) 483 if (idx < 0)
418 { 484 {
419 idx = bidi_cache_idx; 485 idx = bidi_cache_idx;
420 /* Enlarge the cache as needed. */ 486 bidi_cache_ensure_space (idx);
421 if (idx >= bidi_cache_size)
422 {
423 bidi_cache_size += BIDI_CACHE_CHUNK;
424 bidi_cache =
425 (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
426 }
427 /* Character positions should correspond to cache positions 1:1. 487 /* Character positions should correspond to cache positions 1:1.
428 If we are outside the range of cached positions, the cache is 488 If we are outside the range of cached positions, the cache is
429 useless and must be reset. */ 489 useless and must be reset. */
430 if (idx > 0 && 490 if (idx > bidi_cache_start &&
431 (bidi_it->charpos > (bidi_cache[idx - 1].charpos 491 (bidi_it->charpos > (bidi_cache[idx - 1].charpos
432 + bidi_cache[idx - 1].nchars) 492 + bidi_cache[idx - 1].nchars)
433 || bidi_it->charpos < bidi_cache[0].charpos)) 493 || bidi_it->charpos < bidi_cache[bidi_cache_start].charpos))
434 { 494 {
435 bidi_cache_reset (); 495 bidi_cache_reset ();
436 idx = 0; 496 idx = bidi_cache_start;
437 } 497 }
438 if (bidi_it->nchars <= 0) 498 if (bidi_it->nchars <= 0)
439 abort (); 499 abort ();
@@ -468,9 +528,9 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
468static inline bidi_type_t 528static inline bidi_type_t
469bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) 529bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it)
470{ 530{
471 int i = bidi_cache_search (charpos, level, bidi_it->scan_dir); 531 EMACS_INT i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
472 532
473 if (i >= 0) 533 if (i >= bidi_cache_start)
474 { 534 {
475 bidi_dir_t current_scan_dir = bidi_it->scan_dir; 535 bidi_dir_t current_scan_dir = bidi_it->scan_dir;
476 536
@@ -488,69 +548,245 @@ bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it)
488static inline int 548static inline int
489bidi_peek_at_next_level (struct bidi_it *bidi_it) 549bidi_peek_at_next_level (struct bidi_it *bidi_it)
490{ 550{
491 if (bidi_cache_idx == 0 || bidi_cache_last_idx == -1) 551 if (bidi_cache_idx == bidi_cache_start || bidi_cache_last_idx == -1)
492 abort (); 552 abort ();
493 return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level; 553 return bidi_cache[bidi_cache_last_idx + bidi_it->scan_dir].resolved_level;
494} 554}
495 555
496/* Check if buffer position CHARPOS/BYTEPOS is the end of a paragraph. 556
497 Value is the non-negative length of the paragraph separator 557/***********************************************************************
498 following the buffer position, -1 if position is at the beginning 558 Pushing and popping the bidi iterator state
499 of a new paragraph, or -2 if position is neither at beginning nor 559 ***********************************************************************/
500 at end of a paragraph. */ 560/* 5-slot stack for saving the start of the previous level of the
501static EMACS_INT 561 cache. xdisp.c maintains a 5-slot stack for its iterator state,
502bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos) 562 and we need the same size of our stack. */
563static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE];
564static int bidi_cache_sp;
565
566/* Push the bidi iterator state in preparation for reordering a
567 different object, e.g. display string found at certain buffer
568 position. Pushing the bidi iterator boils down to saving its
569 entire state on the cache and starting a new cache "stacked" on top
570 of the current cache. */
571void
572bidi_push_it (struct bidi_it *bidi_it)
503{ 573{
504 Lisp_Object sep_re; 574 /* Save the current iterator state in its entirety after the last
505 Lisp_Object start_re; 575 used cache slot. */
506 EMACS_INT val; 576 bidi_cache_ensure_space (bidi_cache_idx);
577 memcpy (&bidi_cache[bidi_cache_idx++], bidi_it, sizeof (struct bidi_it));
507 578
508 sep_re = paragraph_separate_re; 579 /* Push the current cache start onto the stack. */
509 start_re = paragraph_start_re; 580 xassert (bidi_cache_sp < IT_STACK_SIZE);
581 bidi_cache_start_stack[bidi_cache_sp++] = bidi_cache_start;
510 582
511 val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil); 583 /* Start a new level of cache, and make it empty. */
512 if (val < 0) 584 bidi_cache_start = bidi_cache_idx;
585 bidi_cache_last_idx = -1;
586}
587
588/* Restore the iterator state saved by bidi_push_it and return the
589 cache to the corresponding state. */
590void
591bidi_pop_it (struct bidi_it *bidi_it)
592{
593 if (bidi_cache_start <= 0)
594 abort ();
595
596 /* Reset the next free cache slot index to what it was before the
597 call to bidi_push_it. */
598 bidi_cache_idx = bidi_cache_start - 1;
599
600 /* Restore the bidi iterator state saved in the cache. */
601 memcpy (bidi_it, &bidi_cache[bidi_cache_idx], sizeof (struct bidi_it));
602
603 /* Pop the previous cache start from the stack. */
604 if (bidi_cache_sp <= 0)
605 abort ();
606 bidi_cache_start = bidi_cache_start_stack[--bidi_cache_sp];
607
608 /* Invalidate the last-used cache slot data. */
609 bidi_cache_last_idx = -1;
610}
611
612/* Stash away a copy of the cache and its control variables. */
613void *
614bidi_shelve_cache (void)
615{
616 unsigned char *databuf;
617
618 if (bidi_cache_idx == 0)
619 return NULL;
620
621 databuf = xmalloc (sizeof (bidi_cache_idx)
622 + bidi_cache_idx * sizeof (struct bidi_it)
623 + sizeof (bidi_cache_start_stack)
624 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
625 + sizeof (bidi_cache_last_idx));
626 memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx));
627 memcpy (databuf + sizeof (bidi_cache_idx),
628 bidi_cache, bidi_cache_idx * sizeof (struct bidi_it));
629 memcpy (databuf + sizeof (bidi_cache_idx)
630 + bidi_cache_idx * sizeof (struct bidi_it),
631 bidi_cache_start_stack, sizeof (bidi_cache_start_stack));
632 memcpy (databuf + sizeof (bidi_cache_idx)
633 + bidi_cache_idx * sizeof (struct bidi_it)
634 + sizeof (bidi_cache_start_stack),
635 &bidi_cache_sp, sizeof (bidi_cache_sp));
636 memcpy (databuf + sizeof (bidi_cache_idx)
637 + bidi_cache_idx * sizeof (struct bidi_it)
638 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
639 &bidi_cache_start, sizeof (bidi_cache_start));
640 memcpy (databuf + sizeof (bidi_cache_idx)
641 + bidi_cache_idx * sizeof (struct bidi_it)
642 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
643 + sizeof (bidi_cache_start),
644 &bidi_cache_last_idx, sizeof (bidi_cache_last_idx));
645
646 return databuf;
647}
648
649/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */
650void
651bidi_unshelve_cache (void *databuf)
652{
653 unsigned char *p = databuf;
654
655 if (!p)
513 { 656 {
514 if (fast_looking_at (start_re, charpos, bytepos, ZV, ZV_BYTE, Qnil) >= 0) 657 /* A NULL pointer means an empty cache. */
515 val = -1; 658 bidi_cache_start = 0;
516 else 659 bidi_cache_sp = 0;
517 val = -2; 660 bidi_cache_reset ();
518 } 661 }
662 else
663 {
664 memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx));
665 bidi_cache_ensure_space (bidi_cache_idx);
666 memcpy (bidi_cache, p + sizeof (bidi_cache_idx),
667 bidi_cache_idx * sizeof (struct bidi_it));
668 memcpy (bidi_cache_start_stack,
669 p + sizeof (bidi_cache_idx)
670 + bidi_cache_idx * sizeof (struct bidi_it),
671 sizeof (bidi_cache_start_stack));
672 memcpy (&bidi_cache_sp,
673 p + sizeof (bidi_cache_idx)
674 + bidi_cache_idx * sizeof (struct bidi_it)
675 + sizeof (bidi_cache_start_stack),
676 sizeof (bidi_cache_sp));
677 memcpy (&bidi_cache_start,
678 p + sizeof (bidi_cache_idx)
679 + bidi_cache_idx * sizeof (struct bidi_it)
680 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
681 sizeof (bidi_cache_start));
682 memcpy (&bidi_cache_last_idx,
683 p + sizeof (bidi_cache_idx)
684 + bidi_cache_idx * sizeof (struct bidi_it)
685 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
686 + sizeof (bidi_cache_start),
687 sizeof (bidi_cache_last_idx));
688
689 xfree (p);
690 }
691}
519 692
520 return val; 693
694/***********************************************************************
695 Initialization
696 ***********************************************************************/
697static void
698bidi_initialize (void)
699{
700
701#include "biditype.h"
702#include "bidimirror.h"
703
704 int i;
705
706 bidi_type_table = Fmake_char_table (Qnil, make_number (STRONG_L));
707 staticpro (&bidi_type_table);
708
709 for (i = 0; i < sizeof bidi_type / sizeof bidi_type[0]; i++)
710 char_table_set_range (bidi_type_table, bidi_type[i].from, bidi_type[i].to,
711 make_number (bidi_type[i].type));
712
713 bidi_mirror_table = Fmake_char_table (Qnil, Qnil);
714 staticpro (&bidi_mirror_table);
715
716 for (i = 0; i < sizeof bidi_mirror / sizeof bidi_mirror[0]; i++)
717 char_table_set (bidi_mirror_table, bidi_mirror[i].from,
718 make_number (bidi_mirror[i].to));
719
720 Qparagraph_start = intern ("paragraph-start");
721 staticpro (&Qparagraph_start);
722 paragraph_start_re = Fsymbol_value (Qparagraph_start);
723 if (!STRINGP (paragraph_start_re))
724 paragraph_start_re = build_string ("\f\\|[ \t]*$");
725 staticpro (&paragraph_start_re);
726 Qparagraph_separate = intern ("paragraph-separate");
727 staticpro (&Qparagraph_separate);
728 paragraph_separate_re = Fsymbol_value (Qparagraph_separate);
729 if (!STRINGP (paragraph_separate_re))
730 paragraph_separate_re = build_string ("[ \t\f]*$");
731 staticpro (&paragraph_separate_re);
732
733 bidi_cache_sp = 0;
734
735 bidi_initialized = 1;
521} 736}
522 737
523/* Determine the start-of-run (sor) directional type given the two 738/* Do whatever UAX#9 clause X8 says should be done at paragraph's
524 embedding levels on either side of the run boundary. Also, update 739 end. */
525 the saved info about previously seen characters, since that info is
526 generally valid for a single level run. */
527static inline void 740static inline void
528bidi_set_sor_type (struct bidi_it *bidi_it, int level_before, int level_after) 741bidi_set_paragraph_end (struct bidi_it *bidi_it)
529{ 742{
530 int higher_level = level_before > level_after ? level_before : level_after; 743 bidi_it->invalid_levels = 0;
531 744 bidi_it->invalid_rl_levels = -1;
532 /* The prev_was_pdf gork is required for when we have several PDFs 745 bidi_it->stack_idx = 0;
533 in a row. In that case, we want to compute the sor type for the 746 bidi_it->resolved_level = bidi_it->level_stack[0].level;
534 next level run only once: when we see the first PDF. That's 747}
535 because the sor type depends only on the higher of the two levels
536 that we find on the two sides of the level boundary (see UAX#9,
537 clause X10), and so we don't need to know the final embedding
538 level to which we descend after processing all the PDFs. */
539 if (!bidi_it->prev_was_pdf || level_before < level_after)
540 /* FIXME: should the default sor direction be user selectable? */
541 bidi_it->sor = (higher_level & 1) != 0 ? R2L : L2R;
542 if (level_before > level_after)
543 bidi_it->prev_was_pdf = 1;
544 748
545 bidi_it->prev.type = UNKNOWN_BT; 749/* Initialize the bidi iterator from buffer/string position CHARPOS. */
750void
751bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
752 struct bidi_it *bidi_it)
753{
754 if (! bidi_initialized)
755 bidi_initialize ();
756 if (charpos >= 0)
757 bidi_it->charpos = charpos;
758 if (bytepos >= 0)
759 bidi_it->bytepos = bytepos;
760 bidi_it->frame_window_p = frame_window_p;
761 bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */
762 bidi_it->first_elt = 1;
763 bidi_set_paragraph_end (bidi_it);
764 bidi_it->new_paragraph = 1;
765 bidi_it->separator_limit = -1;
766 bidi_it->type = NEUTRAL_B;
767 bidi_it->type_after_w1 = NEUTRAL_B;
768 bidi_it->orig_type = NEUTRAL_B;
769 bidi_it->prev_was_pdf = 0;
770 bidi_it->prev.type = bidi_it->prev.type_after_w1 =
771 bidi_it->prev.orig_type = UNKNOWN_BT;
546 bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 = 772 bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 =
547 bidi_it->last_strong.orig_type = UNKNOWN_BT; 773 bidi_it->last_strong.orig_type = UNKNOWN_BT;
548 bidi_it->prev_for_neutral.type = bidi_it->sor == R2L ? STRONG_R : STRONG_L; 774 bidi_it->next_for_neutral.charpos = -1;
549 bidi_it->prev_for_neutral.charpos = bidi_it->charpos; 775 bidi_it->next_for_neutral.type =
550 bidi_it->prev_for_neutral.bytepos = bidi_it->bytepos; 776 bidi_it->next_for_neutral.type_after_w1 =
551 bidi_it->next_for_neutral.type = bidi_it->next_for_neutral.type_after_w1 =
552 bidi_it->next_for_neutral.orig_type = UNKNOWN_BT; 777 bidi_it->next_for_neutral.orig_type = UNKNOWN_BT;
553 bidi_it->ignore_bn_limit = 0; /* meaning it's unknown */ 778 bidi_it->prev_for_neutral.charpos = -1;
779 bidi_it->prev_for_neutral.type =
780 bidi_it->prev_for_neutral.type_after_w1 =
781 bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
782 bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */
783 bidi_it->disp_pos = -1; /* invalid/unknown */
784 /* We can only shrink the cache if we are at the bottom level of its
785 "stack". */
786 if (bidi_cache_start == 0)
787 bidi_cache_shrink ();
788 else
789 bidi_cache_reset ();
554} 790}
555 791
556/* Perform initializations for reordering a new line of bidi text. */ 792/* Perform initializations for reordering a new line of bidi text. */
@@ -571,6 +807,57 @@ bidi_line_init (struct bidi_it *bidi_it)
571 bidi_cache_reset (); 807 bidi_cache_reset ();
572} 808}
573 809
810
811/***********************************************************************
812 Fetching characters
813 ***********************************************************************/
814
815/* Count bytes in string S between BEG/BEGBYTE and END. BEG and END
816 are zero-based character positions in S, BEGBYTE is byte position
817 corresponding to BEG. UNIBYTE, if non-zero, means S is a unibyte
818 string. */
819static inline EMACS_INT
820bidi_count_bytes (const unsigned char *s, const EMACS_INT beg,
821 const EMACS_INT begbyte, const EMACS_INT end, int unibyte)
822{
823 EMACS_INT pos = beg;
824 const unsigned char *p = s + begbyte, *start = p;
825
826 if (unibyte)
827 p = s + end;
828 else
829 {
830 if (!CHAR_HEAD_P (*p))
831 abort ();
832
833 while (pos < end)
834 {
835 p += BYTES_BY_CHAR_HEAD (*p);
836 pos++;
837 }
838 }
839
840 return p - start;
841}
842
843/* Fetch and returns the character at byte position BYTEPOS. If S is
844 non-NULL, fetch the character from string S; otherwise fetch the
845 character from the current buffer. UNIBYTE non-zero means S is a
846 unibyte string. */
847static inline int
848bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte)
849{
850 if (s)
851 {
852 if (unibyte)
853 return s[bytepos];
854 else
855 return STRING_CHAR (s + bytepos);
856 }
857 else
858 return FETCH_MULTIBYTE_CHAR (bytepos);
859}
860
574/* Fetch and return the character at BYTEPOS/CHARPOS. If that 861/* Fetch and return the character at BYTEPOS/CHARPOS. If that
575 character is covered by a display string, treat the entire run of 862 character is covered by a display string, treat the entire run of
576 covered characters as a single character u+FFFC, and return their 863 covered characters as a single character u+FFFC, and return their
@@ -578,26 +865,34 @@ bidi_line_init (struct bidi_it *bidi_it)
578 character position of the next display string, or -1 if not yet 865 character position of the next display string, or -1 if not yet
579 computed. When the next character is at or beyond that position, 866 computed. When the next character is at or beyond that position,
580 the function updates DISP_POS with the position of the next display 867 the function updates DISP_POS with the position of the next display
581 string. */ 868 string. STRING->s is the C string to iterate, or NULL if iterating
869 over a buffer or a Lisp string; in the latter case, STRING->lstring
870 is the Lisp string. */
582static inline int 871static inline int
583bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos, 872bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
873 struct bidi_string_data *string,
584 int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars) 874 int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars)
585{ 875{
586 int ch; 876 int ch;
877 EMACS_INT endpos =
878 (string->s || STRINGP (string->lstring)) ? string->schars : ZV;
879 struct text_pos pos;
587 880
588 /* FIXME: Support strings in addition to buffers. */
589 /* If we got past the last known position of display string, compute 881 /* If we got past the last known position of display string, compute
590 the position of the next one. That position could be at BYTEPOS. */ 882 the position of the next one. That position could be at CHARPOS. */
591 if (charpos < ZV && charpos > *disp_pos) 883 if (charpos < endpos && charpos > *disp_pos)
592 *disp_pos = compute_display_string_pos (charpos, frame_window_p); 884 {
885 SET_TEXT_POS (pos, charpos, bytepos);
886 *disp_pos = compute_display_string_pos (&pos, string, frame_window_p);
887 }
593 888
594 /* Fetch the character at BYTEPOS. */ 889 /* Fetch the character at BYTEPOS. */
595 if (bytepos >= ZV_BYTE) 890 if (charpos >= endpos)
596 { 891 {
597 ch = BIDI_EOB; 892 ch = BIDI_EOB;
598 *ch_len = 1; 893 *ch_len = 1;
599 *nchars = 1; 894 *nchars = 1;
600 *disp_pos = ZV; 895 *disp_pos = endpos;
601 } 896 }
602 else if (charpos >= *disp_pos) 897 else if (charpos >= *disp_pos)
603 { 898 {
@@ -608,28 +903,105 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
608 if (charpos > *disp_pos) 903 if (charpos > *disp_pos)
609 abort (); 904 abort ();
610 /* Return the Unicode Object Replacement Character to represent 905 /* Return the Unicode Object Replacement Character to represent
611 the entire run of characters covered by the display 906 the entire run of characters covered by the display string. */
612 string. */
613 ch = 0xFFFC; 907 ch = 0xFFFC;
614 disp_end_pos = compute_display_string_end (*disp_pos); 908 disp_end_pos = compute_display_string_end (*disp_pos, string);
615 *nchars = disp_end_pos - *disp_pos; 909 *nchars = disp_end_pos - *disp_pos;
616 *ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos; 910 if (*nchars <= 0)
911 abort ();
912 if (string->s)
913 *ch_len = bidi_count_bytes (string->s, *disp_pos, bytepos,
914 disp_end_pos, string->unibyte);
915 else if (STRINGP (string->lstring))
916 *ch_len = bidi_count_bytes (SDATA (string->lstring), *disp_pos,
917 bytepos, disp_end_pos, string->unibyte);
918 else
919 *ch_len = CHAR_TO_BYTE (disp_end_pos) - bytepos;
617 } 920 }
618 else 921 else
619 { 922 {
620 ch = FETCH_MULTIBYTE_CHAR (bytepos); 923 if (string->s)
924 {
925 int len;
926
927 if (!string->unibyte)
928 {
929 ch = STRING_CHAR_AND_LENGTH (string->s + bytepos, len);
930 *ch_len = len;
931 }
932 else
933 {
934 ch = UNIBYTE_TO_CHAR (string->s[bytepos]);
935 *ch_len = 1;
936 }
937 }
938 else if (STRINGP (string->lstring))
939 {
940 int len;
941
942 if (!string->unibyte)
943 {
944 ch = STRING_CHAR_AND_LENGTH (SDATA (string->lstring) + bytepos,
945 len);
946 *ch_len = len;
947 }
948 else
949 {
950 ch = UNIBYTE_TO_CHAR (SREF (string->lstring, bytepos));
951 *ch_len = 1;
952 }
953 }
954 else
955 {
956 ch = FETCH_MULTIBYTE_CHAR (bytepos);
957 *ch_len = CHAR_BYTES (ch);
958 }
621 *nchars = 1; 959 *nchars = 1;
622 *ch_len = CHAR_BYTES (ch);
623 } 960 }
624 961
625 /* If we just entered a run of characters covered by a display 962 /* If we just entered a run of characters covered by a display
626 string, compute the position of the next display string. */ 963 string, compute the position of the next display string. */
627 if (charpos + *nchars <= ZV && charpos + *nchars > *disp_pos) 964 if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos)
628 *disp_pos = compute_display_string_pos (charpos + *nchars, frame_window_p); 965 {
966 SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
967 *disp_pos = compute_display_string_pos (&pos, string, frame_window_p);
968 }
629 969
630 return ch; 970 return ch;
631} 971}
632 972
973
974/***********************************************************************
975 Determining paragraph direction
976 ***********************************************************************/
977
978/* Check if buffer position CHARPOS/BYTEPOS is the end of a paragraph.
979 Value is the non-negative length of the paragraph separator
980 following the buffer position, -1 if position is at the beginning
981 of a new paragraph, or -2 if position is neither at beginning nor
982 at end of a paragraph. */
983static EMACS_INT
984bidi_at_paragraph_end (EMACS_INT charpos, EMACS_INT bytepos)
985{
986 Lisp_Object sep_re;
987 Lisp_Object start_re;
988 EMACS_INT val;
989
990 sep_re = paragraph_separate_re;
991 start_re = paragraph_start_re;
992
993 val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil);
994 if (val < 0)
995 {
996 if (fast_looking_at (start_re, charpos, bytepos, ZV, ZV_BYTE, Qnil) >= 0)
997 val = -1;
998 else
999 val = -2;
1000 }
1001
1002 return val;
1003}
1004
633/* Find the beginning of this paragraph by looking back in the buffer. 1005/* Find the beginning of this paragraph by looking back in the buffer.
634 Value is the byte position of the paragraph's beginning. */ 1006 Value is the byte position of the paragraph's beginning. */
635static EMACS_INT 1007static EMACS_INT
@@ -670,13 +1042,19 @@ void
670bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p) 1042bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
671{ 1043{
672 EMACS_INT bytepos = bidi_it->bytepos; 1044 EMACS_INT bytepos = bidi_it->bytepos;
1045 int string_p = bidi_it->string.s != NULL || STRINGP (bidi_it->string.lstring);
673 EMACS_INT pstartbyte; 1046 EMACS_INT pstartbyte;
1047 /* Note that begbyte is a byte position, while end is a character
1048 position. Yes, this is ugly, but we are trying to avoid costly
1049 calls to BYTE_TO_CHAR and its ilk. */
1050 EMACS_INT begbyte = string_p ? 0 : BEGV_BYTE;
1051 EMACS_INT end = string_p ? bidi_it->string.schars : ZV;
674 1052
675 /* Special case for an empty buffer. */ 1053 /* Special case for an empty buffer. */
676 if (bytepos == BEGV_BYTE && bytepos == ZV_BYTE) 1054 if (bytepos == begbyte && bidi_it->charpos == end)
677 dir = L2R; 1055 dir = L2R;
678 /* We should never be called at EOB or before BEGV. */ 1056 /* We should never be called at EOB or before BEGV. */
679 else if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE) 1057 else if (bidi_it->charpos >= end || bytepos < begbyte)
680 abort (); 1058 abort ();
681 1059
682 if (dir == L2R) 1060 if (dir == L2R)
@@ -695,6 +1073,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
695 EMACS_INT ch_len, nchars; 1073 EMACS_INT ch_len, nchars;
696 EMACS_INT pos, disp_pos = -1; 1074 EMACS_INT pos, disp_pos = -1;
697 bidi_type_t type; 1075 bidi_type_t type;
1076 const unsigned char *s;
698 1077
699 if (!bidi_initialized) 1078 if (!bidi_initialized)
700 bidi_initialize (); 1079 bidi_initialize ();
@@ -712,7 +1091,10 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
712 we are potentially in a new paragraph that doesn't yet 1091 we are potentially in a new paragraph that doesn't yet
713 exist. */ 1092 exist. */
714 pos = bidi_it->charpos; 1093 pos = bidi_it->charpos;
715 if (bytepos > BEGV_BYTE && FETCH_CHAR (bytepos) == '\n') 1094 s = STRINGP (bidi_it->string.lstring) ?
1095 SDATA (bidi_it->string.lstring) : bidi_it->string.s;
1096 if (bytepos > begbyte
1097 && bidi_char_at_pos (bytepos, s, bidi_it->string.unibyte) == '\n')
716 { 1098 {
717 bytepos++; 1099 bytepos++;
718 pos++; 1100 pos++;
@@ -720,17 +1102,25 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
720 1102
721 /* We are either at the beginning of a paragraph or in the 1103 /* We are either at the beginning of a paragraph or in the
722 middle of it. Find where this paragraph starts. */ 1104 middle of it. Find where this paragraph starts. */
723 pstartbyte = bidi_find_paragraph_start (pos, bytepos); 1105 if (string_p)
1106 {
1107 /* We don't support changes of paragraph direction inside a
1108 string. It is treated as a single paragraph. */
1109 pstartbyte = 0;
1110 }
1111 else
1112 pstartbyte = bidi_find_paragraph_start (pos, bytepos);
724 bidi_it->separator_limit = -1; 1113 bidi_it->separator_limit = -1;
725 bidi_it->new_paragraph = 0; 1114 bidi_it->new_paragraph = 0;
726 1115
727 /* The following loop is run more than once only if NO_DEFAULT_P 1116 /* The following loop is run more than once only if NO_DEFAULT_P
728 is non-zero. */ 1117 is non-zero, and only if we are iterating on a buffer. */
729 do { 1118 do {
730 bytepos = pstartbyte; 1119 bytepos = pstartbyte;
731 pos = BYTE_TO_CHAR (bytepos); 1120 if (!string_p)
732 ch = bidi_fetch_char (bytepos, pos, &disp_pos, bidi_it->frame_window_p, 1121 pos = BYTE_TO_CHAR (bytepos);
733 &ch_len, &nchars); 1122 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string,
1123 bidi_it->frame_window_p, &ch_len, &nchars);
734 type = bidi_get_type (ch, NEUTRAL_DIR); 1124 type = bidi_get_type (ch, NEUTRAL_DIR);
735 1125
736 for (pos += nchars, bytepos += ch_len; 1126 for (pos += nchars, bytepos += ch_len;
@@ -744,17 +1134,19 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
744 || type == LRE || type == LRO)); 1134 || type == LRE || type == LRO));
745 type = bidi_get_type (ch, NEUTRAL_DIR)) 1135 type = bidi_get_type (ch, NEUTRAL_DIR))
746 { 1136 {
747 if (bytepos >= ZV_BYTE) 1137 if (pos >= end)
748 { 1138 {
749 /* Pretend there's a paragraph separator at end of 1139 /* Pretend there's a paragraph separator at end of
750 buffer. */ 1140 buffer/string. */
751 type = NEUTRAL_B; 1141 type = NEUTRAL_B;
752 break; 1142 break;
753 } 1143 }
754 if (type == NEUTRAL_B && bidi_at_paragraph_end (pos, bytepos) >= -1) 1144 if (!string_p
1145 && type == NEUTRAL_B
1146 && bidi_at_paragraph_end (pos, bytepos) >= -1)
755 break; 1147 break;
756 /* Fetch next character and advance to get past it. */ 1148 /* Fetch next character and advance to get past it. */
757 ch = bidi_fetch_char (bytepos, pos, &disp_pos, 1149 ch = bidi_fetch_char (bytepos, pos, &disp_pos, &bidi_it->string,
758 bidi_it->frame_window_p, &ch_len, &nchars); 1150 bidi_it->frame_window_p, &ch_len, &nchars);
759 pos += nchars; 1151 pos += nchars;
760 bytepos += ch_len; 1152 bytepos += ch_len;
@@ -763,7 +1155,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
763 bidi_it->paragraph_dir = R2L; 1155 bidi_it->paragraph_dir = R2L;
764 else if (type == STRONG_L) 1156 else if (type == STRONG_L)
765 bidi_it->paragraph_dir = L2R; 1157 bidi_it->paragraph_dir = L2R;
766 if (no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR) 1158 if (!string_p
1159 && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR)
767 { 1160 {
768 /* If this paragraph is at BEGV, default to L2R. */ 1161 /* If this paragraph is at BEGV, default to L2R. */
769 if (pstartbyte == BEGV_BYTE) 1162 if (pstartbyte == BEGV_BYTE)
@@ -786,7 +1179,8 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
786 pstartbyte = prevpbyte; 1179 pstartbyte = prevpbyte;
787 } 1180 }
788 } 1181 }
789 } while (no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR); 1182 } while (!string_p
1183 && no_default_p && bidi_it->paragraph_dir == NEUTRAL_DIR);
790 } 1184 }
791 else 1185 else
792 abort (); 1186 abort ();
@@ -804,110 +1198,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
804 bidi_line_init (bidi_it); 1198 bidi_line_init (bidi_it);
805} 1199}
806 1200
807/* Do whatever UAX#9 clause X8 says should be done at paragraph's 1201
808 end. */ 1202/***********************************************************************
809static inline void 1203 Resolving explicit and implicit levels.
810bidi_set_paragraph_end (struct bidi_it *bidi_it) 1204 The rest of this file constitutes the core of the UBA implementation.
811{ 1205 ***********************************************************************/
812 bidi_it->invalid_levels = 0;
813 bidi_it->invalid_rl_levels = -1;
814 bidi_it->stack_idx = 0;
815 bidi_it->resolved_level = bidi_it->level_stack[0].level;
816}
817
818/* Initialize the bidi iterator from buffer/string position CHARPOS. */
819void
820bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
821 struct bidi_it *bidi_it)
822{
823 if (! bidi_initialized)
824 bidi_initialize ();
825 bidi_it->charpos = charpos;
826 bidi_it->bytepos = bytepos;
827 bidi_it->frame_window_p = frame_window_p;
828 bidi_it->nchars = -1; /* to be computed in bidi_resolve_explicit_1 */
829 bidi_it->first_elt = 1;
830 bidi_set_paragraph_end (bidi_it);
831 bidi_it->new_paragraph = 1;
832 bidi_it->separator_limit = -1;
833 bidi_it->type = NEUTRAL_B;
834 bidi_it->type_after_w1 = NEUTRAL_B;
835 bidi_it->orig_type = NEUTRAL_B;
836 bidi_it->prev_was_pdf = 0;
837 bidi_it->prev.type = bidi_it->prev.type_after_w1 =
838 bidi_it->prev.orig_type = UNKNOWN_BT;
839 bidi_it->last_strong.type = bidi_it->last_strong.type_after_w1 =
840 bidi_it->last_strong.orig_type = UNKNOWN_BT;
841 bidi_it->next_for_neutral.charpos = -1;
842 bidi_it->next_for_neutral.type =
843 bidi_it->next_for_neutral.type_after_w1 =
844 bidi_it->next_for_neutral.orig_type = UNKNOWN_BT;
845 bidi_it->prev_for_neutral.charpos = -1;
846 bidi_it->prev_for_neutral.type =
847 bidi_it->prev_for_neutral.type_after_w1 =
848 bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
849 bidi_it->sor = L2R; /* FIXME: should it be user-selectable? */
850 bidi_it->disp_pos = -1; /* invalid/unknown */
851 bidi_cache_shrink ();
852}
853
854/* Push the current embedding level and override status; reset the
855 current level to LEVEL and the current override status to OVERRIDE. */
856static inline void
857bidi_push_embedding_level (struct bidi_it *bidi_it,
858 int level, bidi_dir_t override)
859{
860 bidi_it->stack_idx++;
861 if (bidi_it->stack_idx >= BIDI_MAXLEVEL)
862 abort ();
863 bidi_it->level_stack[bidi_it->stack_idx].level = level;
864 bidi_it->level_stack[bidi_it->stack_idx].override = override;
865}
866
867/* Pop the embedding level and directional override status from the
868 stack, and return the new level. */
869static inline int
870bidi_pop_embedding_level (struct bidi_it *bidi_it)
871{
872 /* UAX#9 says to ignore invalid PDFs. */
873 if (bidi_it->stack_idx > 0)
874 bidi_it->stack_idx--;
875 return bidi_it->level_stack[bidi_it->stack_idx].level;
876}
877
878/* Record in SAVED_INFO the information about the current character. */
879static inline void
880bidi_remember_char (struct bidi_saved_info *saved_info,
881 struct bidi_it *bidi_it)
882{
883 saved_info->charpos = bidi_it->charpos;
884 saved_info->bytepos = bidi_it->bytepos;
885 saved_info->type = bidi_it->type;
886 bidi_check_type (bidi_it->type);
887 saved_info->type_after_w1 = bidi_it->type_after_w1;
888 bidi_check_type (bidi_it->type_after_w1);
889 saved_info->orig_type = bidi_it->orig_type;
890 bidi_check_type (bidi_it->orig_type);
891}
892
893/* Resolve the type of a neutral character according to the type of
894 surrounding strong text and the current embedding level. */
895static inline bidi_type_t
896bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
897{
898 /* N1: European and Arabic numbers are treated as though they were R. */
899 if (next_type == WEAK_EN || next_type == WEAK_AN)
900 next_type = STRONG_R;
901 if (prev_type == WEAK_EN || prev_type == WEAK_AN)
902 prev_type = STRONG_R;
903
904 if (next_type == prev_type) /* N1 */
905 return next_type;
906 else if ((lev & 1) == 0) /* N2 */
907 return STRONG_L;
908 else
909 return STRONG_R;
910}
911 1206
912static inline int 1207static inline int
913bidi_explicit_dir_char (int ch) 1208bidi_explicit_dir_char (int ch)
@@ -934,19 +1229,35 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
934 int current_level; 1229 int current_level;
935 int new_level; 1230 int new_level;
936 bidi_dir_t override; 1231 bidi_dir_t override;
1232 int string_p = bidi_it->string.s != NULL || STRINGP (bidi_it->string.lstring);
937 1233
938 /* If reseat()'ed, don't advance, so as to start iteration from the 1234 /* If reseat()'ed, don't advance, so as to start iteration from the
939 position where we were reseated. bidi_it->bytepos can be less 1235 position where we were reseated. bidi_it->bytepos can be less
940 than BEGV_BYTE after reseat to BEGV. */ 1236 than BEGV_BYTE after reseat to BEGV. */
941 if (bidi_it->bytepos < BEGV_BYTE 1237 if (bidi_it->bytepos < (string_p ? 0 : BEGV_BYTE)
942 || bidi_it->first_elt) 1238 || bidi_it->first_elt)
943 { 1239 {
944 bidi_it->first_elt = 0; 1240 bidi_it->first_elt = 0;
945 if (bidi_it->charpos < BEGV) 1241 if (string_p)
946 bidi_it->charpos = BEGV; 1242 {
947 bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos); 1243 const unsigned char *p =
1244 STRINGP (bidi_it->string.lstring)
1245 ? SDATA (bidi_it->string.lstring) : bidi_it->string.s;
1246
1247 if (bidi_it->charpos < 0)
1248 bidi_it->charpos = 0;
1249 bidi_it->bytepos = bidi_count_bytes (p, 0, 0, bidi_it->charpos,
1250 bidi_it->string.unibyte);
1251 }
1252 else
1253 {
1254 if (bidi_it->charpos < BEGV)
1255 bidi_it->charpos = BEGV;
1256 bidi_it->bytepos = CHAR_TO_BYTE (bidi_it->charpos);
1257 }
948 } 1258 }
949 else if (bidi_it->bytepos < ZV_BYTE) /* don't move at ZV */ 1259 /* Don't move at end of buffer/string. */
1260 else if (bidi_it->charpos < (string_p ? bidi_it->string.schars : ZV))
950 { 1261 {
951 /* Advance to the next character, skipping characters covered by 1262 /* Advance to the next character, skipping characters covered by
952 display strings (nchars > 1). */ 1263 display strings (nchars > 1). */
@@ -962,12 +1273,12 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
962 override = bidi_it->level_stack[bidi_it->stack_idx].override; 1273 override = bidi_it->level_stack[bidi_it->stack_idx].override;
963 new_level = current_level; 1274 new_level = current_level;
964 1275
965 if (bidi_it->bytepos >= ZV_BYTE) 1276 if (bidi_it->charpos >= (string_p ? bidi_it->string.schars : ZV))
966 { 1277 {
967 curchar = BIDI_EOB; 1278 curchar = BIDI_EOB;
968 bidi_it->ch_len = 1; 1279 bidi_it->ch_len = 1;
969 bidi_it->nchars = 1; 1280 bidi_it->nchars = 1;
970 bidi_it->disp_pos = ZV; 1281 bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV);
971 } 1282 }
972 else 1283 else
973 { 1284 {
@@ -975,7 +1286,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
975 display string, treat the entire run of covered characters as 1286 display string, treat the entire run of covered characters as
976 a single character u+FFFC. */ 1287 a single character u+FFFC. */
977 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos, 1288 curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
978 &bidi_it->disp_pos, bidi_it->frame_window_p, 1289 &bidi_it->disp_pos, &bidi_it->string,
1290 bidi_it->frame_window_p,
979 &bidi_it->ch_len, &bidi_it->nchars); 1291 &bidi_it->ch_len, &bidi_it->nchars);
980 } 1292 }
981 bidi_it->ch = curchar; 1293 bidi_it->ch = curchar;
@@ -1000,7 +1312,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1000 bidi_it->type_after_w1 = type; 1312 bidi_it->type_after_w1 = type;
1001 bidi_check_type (bidi_it->type_after_w1); 1313 bidi_check_type (bidi_it->type_after_w1);
1002 type = WEAK_BN; /* X9/Retaining */ 1314 type = WEAK_BN; /* X9/Retaining */
1003 if (bidi_it->ignore_bn_limit <= 0) 1315 if (bidi_it->ignore_bn_limit <= -1)
1004 { 1316 {
1005 if (current_level <= BIDI_MAXLEVEL - 4) 1317 if (current_level <= BIDI_MAXLEVEL - 4)
1006 { 1318 {
@@ -1033,7 +1345,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1033 bidi_it->type_after_w1 = type; 1345 bidi_it->type_after_w1 = type;
1034 bidi_check_type (bidi_it->type_after_w1); 1346 bidi_check_type (bidi_it->type_after_w1);
1035 type = WEAK_BN; /* X9/Retaining */ 1347 type = WEAK_BN; /* X9/Retaining */
1036 if (bidi_it->ignore_bn_limit <= 0) 1348 if (bidi_it->ignore_bn_limit <= -1)
1037 { 1349 {
1038 if (current_level <= BIDI_MAXLEVEL - 5) 1350 if (current_level <= BIDI_MAXLEVEL - 5)
1039 { 1351 {
@@ -1068,7 +1380,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1068 bidi_it->type_after_w1 = type; 1380 bidi_it->type_after_w1 = type;
1069 bidi_check_type (bidi_it->type_after_w1); 1381 bidi_check_type (bidi_it->type_after_w1);
1070 type = WEAK_BN; /* X9/Retaining */ 1382 type = WEAK_BN; /* X9/Retaining */
1071 if (bidi_it->ignore_bn_limit <= 0) 1383 if (bidi_it->ignore_bn_limit <= -1)
1072 { 1384 {
1073 if (!bidi_it->invalid_rl_levels) 1385 if (!bidi_it->invalid_rl_levels)
1074 { 1386 {
@@ -1111,13 +1423,17 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
1111{ 1423{
1112 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level; 1424 int prev_level = bidi_it->level_stack[bidi_it->stack_idx].level;
1113 int new_level = bidi_resolve_explicit_1 (bidi_it); 1425 int new_level = bidi_resolve_explicit_1 (bidi_it);
1426 EMACS_INT eob = bidi_it->string.s ? bidi_it->string.schars : ZV;
1427 const unsigned char *s = STRINGP (bidi_it->string.lstring)
1428 ? SDATA (bidi_it->string.lstring) : bidi_it->string.s;
1114 1429
1115 if (prev_level < new_level 1430 if (prev_level < new_level
1116 && bidi_it->type == WEAK_BN 1431 && bidi_it->type == WEAK_BN
1117 && bidi_it->ignore_bn_limit == 0 /* only if not already known */ 1432 && bidi_it->ignore_bn_limit == -1 /* only if not already known */
1118 && bidi_it->bytepos < ZV_BYTE /* not already at EOB */ 1433 && bidi_it->charpos < eob /* not already at EOB */
1119 && bidi_explicit_dir_char (FETCH_MULTIBYTE_CHAR (bidi_it->bytepos 1434 && bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos
1120 + bidi_it->ch_len))) 1435 + bidi_it->ch_len, s,
1436 bidi_it->string.unibyte)))
1121 { 1437 {
1122 /* Avoid pushing and popping embedding levels if the level run 1438 /* Avoid pushing and popping embedding levels if the level run
1123 is empty, as this breaks level runs where it shouldn't. 1439 is empty, as this breaks level runs where it shouldn't.
@@ -1129,12 +1445,17 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
1129 1445
1130 bidi_copy_it (&saved_it, bidi_it); 1446 bidi_copy_it (&saved_it, bidi_it);
1131 1447
1132 while (bidi_explicit_dir_char (FETCH_MULTIBYTE_CHAR (bidi_it->bytepos 1448 while (bidi_explicit_dir_char (bidi_char_at_pos (bidi_it->bytepos
1133 + bidi_it->ch_len))) 1449 + bidi_it->ch_len, s,
1450 bidi_it->string.unibyte)))
1134 { 1451 {
1135 /* This advances to the next character, skipping any 1452 /* This advances to the next character, skipping any
1136 characters covered by display strings. */ 1453 characters covered by display strings. */
1137 level = bidi_resolve_explicit_1 (bidi_it); 1454 level = bidi_resolve_explicit_1 (bidi_it);
1455 /* If string.lstring was relocated inside bidi_resolve_explicit_1,
1456 a pointer to its data is no longer valid. */
1457 if (STRINGP (bidi_it->string.lstring))
1458 s = SDATA (bidi_it->string.lstring);
1138 } 1459 }
1139 1460
1140 if (bidi_it->nchars <= 0) 1461 if (bidi_it->nchars <= 0)
@@ -1142,10 +1463,10 @@ bidi_resolve_explicit (struct bidi_it *bidi_it)
1142 if (level == prev_level) /* empty embedding */ 1463 if (level == prev_level) /* empty embedding */
1143 saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars; 1464 saved_it.ignore_bn_limit = bidi_it->charpos + bidi_it->nchars;
1144 else /* this embedding is non-empty */ 1465 else /* this embedding is non-empty */
1145 saved_it.ignore_bn_limit = -1; 1466 saved_it.ignore_bn_limit = -2;
1146 1467
1147 bidi_copy_it (bidi_it, &saved_it); 1468 bidi_copy_it (bidi_it, &saved_it);
1148 if (bidi_it->ignore_bn_limit > 0) 1469 if (bidi_it->ignore_bn_limit > -1)
1149 { 1470 {
1150 /* We pushed a level, but we shouldn't have. Undo that. */ 1471 /* We pushed a level, but we shouldn't have. Undo that. */
1151 if (!bidi_it->invalid_rl_levels) 1472 if (!bidi_it->invalid_rl_levels)
@@ -1188,6 +1509,9 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1188 int next_char; 1509 int next_char;
1189 bidi_type_t type_of_next; 1510 bidi_type_t type_of_next;
1190 struct bidi_it saved_it; 1511 struct bidi_it saved_it;
1512 EMACS_INT eob =
1513 (STRINGP (bidi_it->string.lstring) || bidi_it->string.s)
1514 ? bidi_it->string.schars : ZV;
1191 1515
1192 type = bidi_it->type; 1516 type = bidi_it->type;
1193 override = bidi_it->level_stack[bidi_it->stack_idx].override; 1517 override = bidi_it->level_stack[bidi_it->stack_idx].override;
@@ -1254,10 +1578,15 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1254 && bidi_it->prev.orig_type == WEAK_EN) 1578 && bidi_it->prev.orig_type == WEAK_EN)
1255 || bidi_it->prev.type_after_w1 == WEAK_AN))) 1579 || bidi_it->prev.type_after_w1 == WEAK_AN)))
1256 { 1580 {
1581 const unsigned char *s =
1582 STRINGP (bidi_it->string.lstring)
1583 ? SDATA (bidi_it->string.lstring) : bidi_it->string.s;
1584
1257 next_char = 1585 next_char =
1258 bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE 1586 bidi_it->charpos + bidi_it->nchars >= eob
1259 ? BIDI_EOB : FETCH_MULTIBYTE_CHAR (bidi_it->bytepos 1587 ? BIDI_EOB
1260 + bidi_it->ch_len); 1588 : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s,
1589 bidi_it->string.unibyte);
1261 type_of_next = bidi_get_type (next_char, override); 1590 type_of_next = bidi_get_type (next_char, override);
1262 1591
1263 if (type_of_next == WEAK_BN 1592 if (type_of_next == WEAK_BN
@@ -1306,13 +1635,17 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1306 else /* W5: ET/BN with EN after it. */ 1635 else /* W5: ET/BN with EN after it. */
1307 { 1636 {
1308 EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; 1637 EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars;
1638 const unsigned char *s =
1639 STRINGP (bidi_it->string.lstring)
1640 ? SDATA (bidi_it->string.lstring) : bidi_it->string.s;
1309 1641
1310 if (bidi_it->nchars <= 0) 1642 if (bidi_it->nchars <= 0)
1311 abort (); 1643 abort ();
1312 next_char = 1644 next_char =
1313 bidi_it->bytepos + bidi_it->ch_len >= ZV_BYTE 1645 bidi_it->charpos + bidi_it->nchars >= eob
1314 ? BIDI_EOB : FETCH_MULTIBYTE_CHAR (bidi_it->bytepos 1646 ? BIDI_EOB
1315 + bidi_it->ch_len); 1647 : bidi_char_at_pos (bidi_it->bytepos + bidi_it->ch_len, s,
1648 bidi_it->string.unibyte);
1316 type_of_next = bidi_get_type (next_char, override); 1649 type_of_next = bidi_get_type (next_char, override);
1317 1650
1318 if (type_of_next == WEAK_ET 1651 if (type_of_next == WEAK_ET
@@ -1373,6 +1706,25 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1373 return type; 1706 return type;
1374} 1707}
1375 1708
1709/* Resolve the type of a neutral character according to the type of
1710 surrounding strong text and the current embedding level. */
1711static inline bidi_type_t
1712bidi_resolve_neutral_1 (bidi_type_t prev_type, bidi_type_t next_type, int lev)
1713{
1714 /* N1: European and Arabic numbers are treated as though they were R. */
1715 if (next_type == WEAK_EN || next_type == WEAK_AN)
1716 next_type = STRONG_R;
1717 if (prev_type == WEAK_EN || prev_type == WEAK_AN)
1718 prev_type = STRONG_R;
1719
1720 if (next_type == prev_type) /* N1 */
1721 return next_type;
1722 else if ((lev & 1) == 0) /* N2 */
1723 return STRONG_L;
1724 else
1725 return STRONG_R;
1726}
1727
1376static bidi_type_t 1728static bidi_type_t
1377bidi_resolve_neutral (struct bidi_it *bidi_it) 1729bidi_resolve_neutral (struct bidi_it *bidi_it)
1378{ 1730{
@@ -1509,11 +1861,11 @@ bidi_type_of_next_char (struct bidi_it *bidi_it)
1509 1861
1510 /* Reset the limit until which to ignore BNs if we step out of the 1862 /* Reset the limit until which to ignore BNs if we step out of the
1511 area where we found only empty levels. */ 1863 area where we found only empty levels. */
1512 if ((bidi_it->ignore_bn_limit > 0 1864 if ((bidi_it->ignore_bn_limit > -1
1513 && bidi_it->ignore_bn_limit <= bidi_it->charpos) 1865 && bidi_it->ignore_bn_limit <= bidi_it->charpos)
1514 || (bidi_it->ignore_bn_limit == -1 1866 || (bidi_it->ignore_bn_limit == -2
1515 && !bidi_explicit_dir_char (bidi_it->ch))) 1867 && !bidi_explicit_dir_char (bidi_it->ch)))
1516 bidi_it->ignore_bn_limit = 0; 1868 bidi_it->ignore_bn_limit = -1;
1517 1869
1518 type = bidi_resolve_neutral (bidi_it); 1870 type = bidi_resolve_neutral (bidi_it);
1519 1871
@@ -1530,12 +1882,16 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
1530 bidi_type_t type; 1882 bidi_type_t type;
1531 int level, prev_level = -1; 1883 int level, prev_level = -1;
1532 struct bidi_saved_info next_for_neutral; 1884 struct bidi_saved_info next_for_neutral;
1533 EMACS_INT next_char_pos; 1885 EMACS_INT next_char_pos = -2;
1534 1886
1535 if (bidi_it->scan_dir == 1) 1887 if (bidi_it->scan_dir == 1)
1536 { 1888 {
1889 EMACS_INT eob =
1890 (bidi_it->string.s || STRINGP (bidi_it->string.lstring))
1891 ? bidi_it->string.schars : ZV;
1892
1537 /* There's no sense in trying to advance if we hit end of text. */ 1893 /* There's no sense in trying to advance if we hit end of text. */
1538 if (bidi_it->bytepos >= ZV_BYTE) 1894 if (bidi_it->charpos >= eob)
1539 return bidi_it->resolved_level; 1895 return bidi_it->resolved_level;
1540 1896
1541 /* Record the info about the previous character. */ 1897 /* Record the info about the previous character. */
@@ -1575,17 +1931,27 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
1575 /* Perhaps the character we want is already cached. If it is, the 1931 /* Perhaps the character we want is already cached. If it is, the
1576 call to bidi_cache_find below will return a type other than 1932 call to bidi_cache_find below will return a type other than
1577 UNKNOWN_BT. */ 1933 UNKNOWN_BT. */
1578 if (bidi_cache_idx && !bidi_it->first_elt) 1934 if (bidi_cache_idx > bidi_cache_start && !bidi_it->first_elt)
1579 { 1935 {
1936 int bob =
1937 (bidi_it->string.s || STRINGP (bidi_it->string.lstring)) ? 0 : 1;
1938
1580 if (bidi_it->scan_dir > 0) 1939 if (bidi_it->scan_dir > 0)
1581 { 1940 {
1582 if (bidi_it->nchars <= 0) 1941 if (bidi_it->nchars <= 0)
1583 abort (); 1942 abort ();
1584 next_char_pos = bidi_it->charpos + bidi_it->nchars; 1943 next_char_pos = bidi_it->charpos + bidi_it->nchars;
1585 } 1944 }
1586 else 1945 else if (bidi_it->charpos >= bob)
1946 /* Implementation note: we allow next_char_pos to be as low as
1947 0 for buffers or -1 for strings, and that is okay because
1948 that's the "position" of the sentinel iterator state we
1949 cached at the beginning of the iteration. */
1587 next_char_pos = bidi_it->charpos - 1; 1950 next_char_pos = bidi_it->charpos - 1;
1588 type = bidi_cache_find (next_char_pos, -1, bidi_it); 1951 if (next_char_pos >= bob - 1)
1952 type = bidi_cache_find (next_char_pos, -1, bidi_it);
1953 else
1954 type = UNKNOWN_BT;
1589 } 1955 }
1590 else 1956 else
1591 type = UNKNOWN_BT; 1957 type = UNKNOWN_BT;
@@ -1652,13 +2018,14 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
1652 EMACS_INT cpos = bidi_it->charpos; 2018 EMACS_INT cpos = bidi_it->charpos;
1653 EMACS_INT disp_pos = bidi_it->disp_pos; 2019 EMACS_INT disp_pos = bidi_it->disp_pos;
1654 EMACS_INT nc = bidi_it->nchars; 2020 EMACS_INT nc = bidi_it->nchars;
2021 struct bidi_string_data bs = bidi_it->string;
1655 bidi_type_t chtype; 2022 bidi_type_t chtype;
1656 int fwp = bidi_it->frame_window_p; 2023 int fwp = bidi_it->frame_window_p;
1657 2024
1658 if (bidi_it->nchars <= 0) 2025 if (bidi_it->nchars <= 0)
1659 abort (); 2026 abort ();
1660 do { 2027 do {
1661 ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, fwp, 2028 ch = bidi_fetch_char (bpos += clen, cpos += nc, &disp_pos, &bs, fwp,
1662 &clen, &nc); 2029 &clen, &nc);
1663 if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */) 2030 if (ch == '\n' || ch == BIDI_EOB /* || ch == LINESEP_CHAR */)
1664 chtype = NEUTRAL_B; 2031 chtype = NEUTRAL_B;
@@ -1756,10 +2123,11 @@ static void
1756bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) 2123bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag)
1757{ 2124{
1758 int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; 2125 int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir;
1759 int idx; 2126 EMACS_INT idx;
1760 2127
1761 /* Try the cache first. */ 2128 /* Try the cache first. */
1762 if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) >= 0) 2129 if ((idx = bidi_cache_find_level_change (level, dir, end_flag))
2130 >= bidi_cache_start)
1763 bidi_cache_fetch_state (idx, bidi_it); 2131 bidi_cache_fetch_state (idx, bidi_it);
1764 else 2132 else
1765 { 2133 {
@@ -1781,12 +2149,21 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
1781{ 2149{
1782 int old_level, new_level, next_level; 2150 int old_level, new_level, next_level;
1783 struct bidi_it sentinel; 2151 struct bidi_it sentinel;
2152 struct gcpro gcpro1;
2153
2154 if (bidi_it->charpos < 0 || bidi_it->bytepos < 0)
2155 abort ();
1784 2156
1785 if (bidi_it->scan_dir == 0) 2157 if (bidi_it->scan_dir == 0)
1786 { 2158 {
1787 bidi_it->scan_dir = 1; /* default to logical order */ 2159 bidi_it->scan_dir = 1; /* default to logical order */
1788 } 2160 }
1789 2161
2162 /* The code below can call eval, and thus cause GC. If we are
2163 iterating a Lisp string, make sure it won't be GCed. */
2164 if (STRINGP (bidi_it->string.lstring))
2165 GCPRO1 (bidi_it->string.lstring);
2166
1790 /* If we just passed a newline, initialize for the next line. */ 2167 /* If we just passed a newline, initialize for the next line. */
1791 if (!bidi_it->first_elt && bidi_it->orig_type == NEUTRAL_B) 2168 if (!bidi_it->first_elt && bidi_it->orig_type == NEUTRAL_B)
1792 bidi_line_init (bidi_it); 2169 bidi_line_init (bidi_it);
@@ -1794,7 +2171,7 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
1794 /* Prepare the sentinel iterator state, and cache it. When we bump 2171 /* Prepare the sentinel iterator state, and cache it. When we bump
1795 into it, scanning backwards, we'll know that the last non-base 2172 into it, scanning backwards, we'll know that the last non-base
1796 level is exhausted. */ 2173 level is exhausted. */
1797 if (bidi_cache_idx == 0) 2174 if (bidi_cache_idx == bidi_cache_start)
1798 { 2175 {
1799 bidi_copy_it (&sentinel, bidi_it); 2176 bidi_copy_it (&sentinel, bidi_it);
1800 if (bidi_it->first_elt) 2177 if (bidi_it->first_elt)
@@ -1869,26 +2246,34 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
1869 reordering, whereas we _must_ know the paragraph base direction 2246 reordering, whereas we _must_ know the paragraph base direction
1870 _before_ we process the paragraph's text, since the base 2247 _before_ we process the paragraph's text, since the base
1871 direction affects the reordering. */ 2248 direction affects the reordering. */
1872 if (bidi_it->scan_dir == 1 2249 if (bidi_it->scan_dir == 1 && bidi_it->orig_type == NEUTRAL_B)
1873 && bidi_it->orig_type == NEUTRAL_B
1874 && bidi_it->bytepos < ZV_BYTE)
1875 { 2250 {
1876 EMACS_INT sep_len = 2251 /* The paragraph direction of the entire string, once
1877 bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars, 2252 determined, is in effect for the entire string. Setting the
1878 bidi_it->bytepos + bidi_it->ch_len); 2253 separator limit to the end of the string prevents
1879 if (bidi_it->nchars <= 0) 2254 bidi_paragraph_init from being called automatically on this
1880 abort (); 2255 string. */
1881 if (sep_len >= 0) 2256 if (bidi_it->string.s || STRINGP (bidi_it->string.lstring))
2257 bidi_it->separator_limit = bidi_it->string.schars;
2258 else if (bidi_it->bytepos < ZV_BYTE)
1882 { 2259 {
1883 bidi_it->new_paragraph = 1; 2260 EMACS_INT sep_len =
1884 /* Record the buffer position of the last character of the 2261 bidi_at_paragraph_end (bidi_it->charpos + bidi_it->nchars,
1885 paragraph separator. */ 2262 bidi_it->bytepos + bidi_it->ch_len);
1886 bidi_it->separator_limit = 2263 if (bidi_it->nchars <= 0)
1887 bidi_it->charpos + bidi_it->nchars + sep_len; 2264 abort ();
2265 if (sep_len >= 0)
2266 {
2267 bidi_it->new_paragraph = 1;
2268 /* Record the buffer position of the last character of the
2269 paragraph separator. */
2270 bidi_it->separator_limit =
2271 bidi_it->charpos + bidi_it->nchars + sep_len;
2272 }
1888 } 2273 }
1889 } 2274 }
1890 2275
1891 if (bidi_it->scan_dir == 1 && bidi_cache_idx) 2276 if (bidi_it->scan_dir == 1 && bidi_cache_idx > bidi_cache_start)
1892 { 2277 {
1893 /* If we are at paragraph's base embedding level and beyond the 2278 /* If we are at paragraph's base embedding level and beyond the
1894 last cached position, the cache's job is done and we can 2279 last cached position, the cache's job is done and we can
@@ -1904,6 +2289,9 @@ bidi_move_to_visually_next (struct bidi_it *bidi_it)
1904 else 2289 else
1905 bidi_cache_iterator_state (bidi_it, 1); 2290 bidi_cache_iterator_state (bidi_it, 1);
1906 } 2291 }
2292
2293 if (STRINGP (bidi_it->string.lstring))
2294 UNGCPRO;
1907} 2295}
1908 2296
1909/* This is meant to be called from within the debugger, whenever you 2297/* This is meant to be called from within the debugger, whenever you
@@ -1920,7 +2308,7 @@ bidi_dump_cached_states (void)
1920 fprintf (stderr, "The cache is empty.\n"); 2308 fprintf (stderr, "The cache is empty.\n");
1921 return; 2309 return;
1922 } 2310 }
1923 fprintf (stderr, "Total of %d state%s in cache:\n", 2311 fprintf (stderr, "Total of %"pD"d state%s in cache:\n",
1924 bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s"); 2312 bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s");
1925 2313
1926 for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10) 2314 for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10)
diff --git a/src/buffer.c b/src/buffer.c
index 328963be78c..81c537b9c6a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -146,7 +146,7 @@ static Lisp_Object Qoverlayp;
146 146
147Lisp_Object Qpriority, Qbefore_string, Qafter_string; 147Lisp_Object Qpriority, Qbefore_string, Qafter_string;
148 148
149static Lisp_Object Qclone_number, Qevaporate; 149static Lisp_Object Qevaporate;
150 150
151Lisp_Object Qmodification_hooks; 151Lisp_Object Qmodification_hooks;
152Lisp_Object Qinsert_in_front_hooks; 152Lisp_Object Qinsert_in_front_hooks;
@@ -361,6 +361,7 @@ even if it is dead. The return value is never nil. */)
361 BUF_END_UNCHANGED (b) = 0; 361 BUF_END_UNCHANGED (b) = 0;
362 BUF_BEG_UNCHANGED (b) = 0; 362 BUF_BEG_UNCHANGED (b) = 0;
363 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ 363 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
364 b->text->inhibit_shrinking = 0;
364 365
365 b->newline_cache = 0; 366 b->newline_cache = 0;
366 b->width_run_cache = 0; 367 b->width_run_cache = 0;
@@ -471,8 +472,8 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to)
471 472
472 /* buffer-local Lisp variables start at `undo_list', 473 /* buffer-local Lisp variables start at `undo_list',
473 tho only the ones from `name' on are GC'd normally. */ 474 tho only the ones from `name' on are GC'd normally. */
474 for (offset = PER_BUFFER_VAR_OFFSET (undo_list); 475 for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
475 offset < sizeof *to; 476 offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
476 offset += sizeof (Lisp_Object)) 477 offset += sizeof (Lisp_Object))
477 { 478 {
478 Lisp_Object obj; 479 Lisp_Object obj;
@@ -830,8 +831,8 @@ reset_buffer_local_variables (register struct buffer *b, int permanent_too)
830 831
831 /* buffer-local Lisp variables start at `undo_list', 832 /* buffer-local Lisp variables start at `undo_list',
832 tho only the ones from `name' on are GC'd normally. */ 833 tho only the ones from `name' on are GC'd normally. */
833 for (offset = PER_BUFFER_VAR_OFFSET (undo_list); 834 for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
834 offset < sizeof *b; 835 offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
835 offset += sizeof (Lisp_Object)) 836 offset += sizeof (Lisp_Object))
836 { 837 {
837 int idx = PER_BUFFER_IDX (offset); 838 int idx = PER_BUFFER_IDX (offset);
@@ -1055,8 +1056,8 @@ No argument or nil as argument means use current buffer as BUFFER. */)
1055 1056
1056 /* buffer-local Lisp variables start at `undo_list', 1057 /* buffer-local Lisp variables start at `undo_list',
1057 tho only the ones from `name' on are GC'd normally. */ 1058 tho only the ones from `name' on are GC'd normally. */
1058 for (offset = PER_BUFFER_VAR_OFFSET (undo_list); 1059 for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
1059 offset < sizeof (struct buffer); 1060 offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
1060 /* sizeof EMACS_INT == sizeof Lisp_Object */ 1061 /* sizeof EMACS_INT == sizeof Lisp_Object */
1061 offset += (sizeof (EMACS_INT))) 1062 offset += (sizeof (EMACS_INT)))
1062 { 1063 {
@@ -2900,13 +2901,10 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
2900 overlays that are limited to some other window. */ 2901 overlays that are limited to some other window. */
2901 if (w) 2902 if (w)
2902 { 2903 {
2903 Lisp_Object window, clone_number; 2904 Lisp_Object window;
2904 2905
2905 window = Foverlay_get (overlay, Qwindow); 2906 window = Foverlay_get (overlay, Qwindow);
2906 clone_number = Foverlay_get (overlay, Qclone_number); 2907 if (WINDOWP (window) && XWINDOW (window) != w)
2907 if (WINDOWP (window) && XWINDOW (window) != w
2908 && (! NUMBERP (clone_number)
2909 || XFASTINT (clone_number) != XFASTINT (w->clone_number)))
2910 continue; 2908 continue;
2911 } 2909 }
2912 2910
@@ -3035,7 +3033,7 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
3035EMACS_INT 3033EMACS_INT
3036overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr) 3034overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
3037{ 3035{
3038 Lisp_Object overlay, window, clone_number, str; 3036 Lisp_Object overlay, window, str;
3039 struct Lisp_Overlay *ov; 3037 struct Lisp_Overlay *ov;
3040 EMACS_INT startpos, endpos; 3038 EMACS_INT startpos, endpos;
3041 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3039 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
@@ -3054,12 +3052,8 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
3054 if (endpos != pos && startpos != pos) 3052 if (endpos != pos && startpos != pos)
3055 continue; 3053 continue;
3056 window = Foverlay_get (overlay, Qwindow); 3054 window = Foverlay_get (overlay, Qwindow);
3057 clone_number = Foverlay_get (overlay, Qclone_number); 3055 if (WINDOWP (window) && XWINDOW (window) != w)
3058 if (WINDOWP (window) && XWINDOW (window) != w
3059 && (! NUMBERP (clone_number)
3060 || XFASTINT (clone_number) != XFASTINT (w->clone_number)))
3061 continue; 3056 continue;
3062
3063 if (startpos == pos 3057 if (startpos == pos
3064 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3058 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3065 record_overlay_string (&overlay_heads, str, 3059 record_overlay_string (&overlay_heads, str,
@@ -3086,10 +3080,7 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
3086 if (endpos != pos && startpos != pos) 3080 if (endpos != pos && startpos != pos)
3087 continue; 3081 continue;
3088 window = Foverlay_get (overlay, Qwindow); 3082 window = Foverlay_get (overlay, Qwindow);
3089 clone_number = Foverlay_get (overlay, Qclone_number); 3083 if (WINDOWP (window) && XWINDOW (window) != w)
3090 if (WINDOWP (window) && XWINDOW (window) != w
3091 && (! NUMBERP (clone_number)
3092 || XFASTINT (clone_number) != XFASTINT (w->clone_number)))
3093 continue; 3084 continue;
3094 if (startpos == pos 3085 if (startpos == pos
3095 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3086 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
@@ -4066,7 +4057,8 @@ DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
4066} 4057}
4067 4058
4068DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0, 4059DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
4069 doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE. */) 4060 doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE.
4061VALUE will be returned.*/)
4070 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value) 4062 (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
4071{ 4063{
4072 Lisp_Object tail, buffer; 4064 Lisp_Object tail, buffer;
@@ -4475,24 +4467,40 @@ static int mmap_initialized_p;
4475#define MMAP_ALLOCATED_P(start, end) 1 4467#define MMAP_ALLOCATED_P(start, end) 1
4476#endif 4468#endif
4477 4469
4478/* Function prototypes. */ 4470/* Perform necessary intializations for the use of mmap. */
4479 4471
4480static int mmap_free_1 (struct mmap_region *); 4472static void
4481static int mmap_enlarge (struct mmap_region *, int); 4473mmap_init (void)
4482static struct mmap_region *mmap_find (POINTER_TYPE *, POINTER_TYPE *); 4474{
4483static POINTER_TYPE *mmap_alloc (POINTER_TYPE **, size_t); 4475#if MAP_ANON == 0
4484static POINTER_TYPE *mmap_realloc (POINTER_TYPE **, size_t); 4476 /* The value of mmap_fd is initially 0 in temacs, and -1
4485static void mmap_free (POINTER_TYPE **ptr); 4477 in a dumped Emacs. */
4486static void mmap_init (void); 4478 if (mmap_fd <= 0)
4479 {
4480 /* No anonymous mmap -- we need the file descriptor. */
4481 mmap_fd = open ("/dev/zero", O_RDONLY);
4482 if (mmap_fd == -1)
4483 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4484 }
4485#endif /* MAP_ANON == 0 */
4487 4486
4487 if (mmap_initialized_p)
4488 return;
4489 mmap_initialized_p = 1;
4490
4491#if MAP_ANON != 0
4492 mmap_fd = -1;
4493#endif
4494
4495 mmap_page_size = getpagesize ();
4496}
4488 4497
4489/* Return a region overlapping address range START...END, or null if 4498/* Return a region overlapping address range START...END, or null if
4490 none. END is not including, i.e. the last byte in the range 4499 none. END is not including, i.e. the last byte in the range
4491 is at END - 1. */ 4500 is at END - 1. */
4492 4501
4493static struct mmap_region * 4502static struct mmap_region *
4494mmap_find (start, end) 4503mmap_find (POINTER_TYPE *start, POINTER_TYPE *end)
4495 POINTER_TYPE *start, *end;
4496{ 4504{
4497 struct mmap_region *r; 4505 struct mmap_region *r;
4498 char *s = (char *) start, *e = (char *) end; 4506 char *s = (char *) start, *e = (char *) end;
@@ -4521,8 +4529,7 @@ mmap_find (start, end)
4521 the region. Value is non-zero if successful. */ 4529 the region. Value is non-zero if successful. */
4522 4530
4523static int 4531static int
4524mmap_free_1 (r) 4532mmap_free_1 (struct mmap_region *r)
4525 struct mmap_region *r;
4526{ 4533{
4527 if (r->next) 4534 if (r->next)
4528 r->next->prev = r->prev; 4535 r->next->prev = r->prev;
@@ -4545,9 +4552,7 @@ mmap_free_1 (r)
4545 Value is non-zero if successful. */ 4552 Value is non-zero if successful. */
4546 4553
4547static int 4554static int
4548mmap_enlarge (r, npages) 4555mmap_enlarge (struct mmap_region *r, int npages)
4549 struct mmap_region *r;
4550 int npages;
4551{ 4556{
4552 char *region_end = (char *) r + r->nbytes_mapped; 4557 char *region_end = (char *) r + r->nbytes_mapped;
4553 size_t nbytes; 4558 size_t nbytes;
@@ -4611,8 +4616,7 @@ mmap_enlarge (r, npages)
4611 when Emacs starts. */ 4616 when Emacs starts. */
4612 4617
4613void 4618void
4614mmap_set_vars (restore_p) 4619mmap_set_vars (int restore_p)
4615 int restore_p;
4616{ 4620{
4617 struct mmap_region *r; 4621 struct mmap_region *r;
4618 4622
@@ -4645,9 +4649,7 @@ mmap_set_vars (restore_p)
4645 return null. */ 4649 return null. */
4646 4650
4647static POINTER_TYPE * 4651static POINTER_TYPE *
4648mmap_alloc (var, nbytes) 4652mmap_alloc (POINTER_TYPE **var, size_t nbytes)
4649 POINTER_TYPE **var;
4650 size_t nbytes;
4651{ 4653{
4652 void *p; 4654 void *p;
4653 size_t map; 4655 size_t map;
@@ -4684,15 +4686,29 @@ mmap_alloc (var, nbytes)
4684} 4686}
4685 4687
4686 4688
4689/* Free a block of relocatable storage whose data is pointed to by
4690 PTR. Store 0 in *PTR to show there's no block allocated. */
4691
4692static void
4693mmap_free (POINTER_TYPE **var)
4694{
4695 mmap_init ();
4696
4697 if (*var)
4698 {
4699 mmap_free_1 (MMAP_REGION (*var));
4700 *var = NULL;
4701 }
4702}
4703
4704
4687/* Given a pointer at address VAR to data allocated with mmap_alloc, 4705/* Given a pointer at address VAR to data allocated with mmap_alloc,
4688 resize it to size NBYTES. Change *VAR to reflect the new block, 4706 resize it to size NBYTES. Change *VAR to reflect the new block,
4689 and return this value. If more memory cannot be allocated, then 4707 and return this value. If more memory cannot be allocated, then
4690 leave *VAR unchanged, and return null. */ 4708 leave *VAR unchanged, and return null. */
4691 4709
4692static POINTER_TYPE * 4710static POINTER_TYPE *
4693mmap_realloc (var, nbytes) 4711mmap_realloc (POINTER_TYPE **var, size_t nbytes)
4694 POINTER_TYPE **var;
4695 size_t nbytes;
4696{ 4712{
4697 POINTER_TYPE *result; 4713 POINTER_TYPE *result;
4698 4714
@@ -4762,51 +4778,6 @@ mmap_realloc (var, nbytes)
4762} 4778}
4763 4779
4764 4780
4765/* Free a block of relocatable storage whose data is pointed to by
4766 PTR. Store 0 in *PTR to show there's no block allocated. */
4767
4768static void
4769mmap_free (var)
4770 POINTER_TYPE **var;
4771{
4772 mmap_init ();
4773
4774 if (*var)
4775 {
4776 mmap_free_1 (MMAP_REGION (*var));
4777 *var = NULL;
4778 }
4779}
4780
4781
4782/* Perform necessary intializations for the use of mmap. */
4783
4784static void
4785mmap_init ()
4786{
4787#if MAP_ANON == 0
4788 /* The value of mmap_fd is initially 0 in temacs, and -1
4789 in a dumped Emacs. */
4790 if (mmap_fd <= 0)
4791 {
4792 /* No anonymous mmap -- we need the file descriptor. */
4793 mmap_fd = open ("/dev/zero", O_RDONLY);
4794 if (mmap_fd == -1)
4795 fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
4796 }
4797#endif /* MAP_ANON == 0 */
4798
4799 if (mmap_initialized_p)
4800 return;
4801 mmap_initialized_p = 1;
4802
4803#if MAP_ANON != 0
4804 mmap_fd = -1;
4805#endif
4806
4807 mmap_page_size = getpagesize ();
4808}
4809
4810#endif /* USE_MMAP_FOR_BUFFERS */ 4781#endif /* USE_MMAP_FOR_BUFFERS */
4811 4782
4812 4783
@@ -5229,7 +5200,6 @@ syms_of_buffer (void)
5229 DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks"); 5200 DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks");
5230 DEFSYM (Qget_file_buffer, "get-file-buffer"); 5201 DEFSYM (Qget_file_buffer, "get-file-buffer");
5231 DEFSYM (Qpriority, "priority"); 5202 DEFSYM (Qpriority, "priority");
5232 DEFSYM (Qclone_number, "clone-number");
5233 DEFSYM (Qbefore_string, "before-string"); 5203 DEFSYM (Qbefore_string, "before-string");
5234 DEFSYM (Qafter_string, "after-string"); 5204 DEFSYM (Qafter_string, "after-string");
5235 DEFSYM (Qfirst_change_hook, "first-change-hook"); 5205 DEFSYM (Qfirst_change_hook, "first-change-hook");
diff --git a/src/buffer.h b/src/buffer.h
index 4643e0d9d0e..06864dd5789 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -612,6 +612,7 @@ struct buffer
612 /* Everything from here down must be a Lisp_Object. */ 612 /* Everything from here down must be a Lisp_Object. */
613 /* buffer-local Lisp variables start at `undo_list', 613 /* buffer-local Lisp variables start at `undo_list',
614 tho only the ones from `name' on are GC'd normally. */ 614 tho only the ones from `name' on are GC'd normally. */
615 #define FIRST_FIELD_PER_BUFFER undo_list
615 616
616 /* Changes in the buffer are recorded here for undo. 617 /* Changes in the buffer are recorded here for undo.
617 t means don't record anything. 618 t means don't record anything.
@@ -846,6 +847,9 @@ struct buffer
846 t means to use hollow box cursor. 847 t means to use hollow box cursor.
847 See `cursor-type' for other values. */ 848 See `cursor-type' for other values. */
848 Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows); 849 Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows);
850
851 /* This must be the last field in the above list. */
852 #define LAST_FIELD_PER_BUFFER cursor_in_non_selected_windows
849}; 853};
850 854
851 855
diff --git a/src/callint.c b/src/callint.c
index 4d0a2a07921..26b161a25b3 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -105,9 +105,10 @@ Z -- Coding system, nil if no prefix arg.
105 105
106In addition, if the string begins with `*', an error is signaled if 106In addition, if the string begins with `*', an error is signaled if
107 the buffer is read-only. 107 the buffer is read-only.
108If the string begins with `@', Emacs searches the key sequence which 108If `@' appears at the beginning of the string, and if the key sequence
109 invoked the command for its first mouse click (or any other event 109 used to invoke the command includes any mouse events, then the window
110 which specifies a window). 110 associated with the first of those events is selected before the
111 command is run.
111If the string begins with `^' and `shift-select-mode' is non-nil, 112If the string begins with `^' and `shift-select-mode' is non-nil,
112 Emacs first calls the function `handle-shift-selection'. 113 Emacs first calls the function `handle-shift-selection'.
113You may use `@', `*', and `^' together. They are processed in the 114You may use `@', `*', and `^' together. They are processed in the
@@ -233,7 +234,7 @@ fix_command (Lisp_Object input, Lisp_Object values)
233} 234}
234 235
235DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0, 236DEFUN ("call-interactively", Fcall_interactively, Scall_interactively, 1, 3, 0,
236 doc: /* Call FUNCTION, reading args according to its interactive calling specs. 237 doc: /* Call FUNCTION, providing args according to its interactive calling specs.
237Return the value FUNCTION returns. 238Return the value FUNCTION returns.
238The function contains a specification of how to do the argument reading. 239The function contains a specification of how to do the argument reading.
239In the case of user-defined functions, this is specified by placing a call 240In the case of user-defined functions, this is specified by placing a call
diff --git a/src/callproc.c b/src/callproc.c
index b339f343f62..ad3eddbdd39 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -596,7 +596,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
596 sigemptyset (&blocked); 596 sigemptyset (&blocked);
597 sigaddset (&blocked, SIGPIPE); 597 sigaddset (&blocked, SIGPIPE);
598 sigaction (SIGPIPE, 0, &sigpipe_action); 598 sigaction (SIGPIPE, 0, &sigpipe_action);
599 sigprocmask (SIG_BLOCK, &blocked, &procmask); 599 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
600#endif 600#endif
601 601
602 BLOCK_INPUT; 602 BLOCK_INPUT;
@@ -633,7 +633,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
633 in the child. */ 633 in the child. */
634 //signal (SIGPIPE, SIG_DFL); 634 //signal (SIGPIPE, SIG_DFL);
635#ifdef HAVE_WORKING_VFORK 635#ifdef HAVE_WORKING_VFORK
636 sigprocmask (SIG_SETMASK, &procmask, 0); 636 pthread_sigmask (SIG_SETMASK, &procmask, 0);
637#endif 637#endif
638 638
639 child_setup (filefd, fd1, fd_error, (char **) new_argv, 639 child_setup (filefd, fd1, fd_error, (char **) new_argv,
@@ -645,7 +645,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
645#ifdef HAVE_WORKING_VFORK 645#ifdef HAVE_WORKING_VFORK
646 /* Restore the signal state. */ 646 /* Restore the signal state. */
647 sigaction (SIGPIPE, &sigpipe_action, 0); 647 sigaction (SIGPIPE, &sigpipe_action, 0);
648 sigprocmask (SIG_SETMASK, &procmask, 0); 648 pthread_sigmask (SIG_SETMASK, &procmask, 0);
649#endif 649#endif
650 650
651#endif /* not WINDOWSNT */ 651#endif /* not WINDOWSNT */
diff --git a/src/character.c b/src/character.c
index 7fc5d647ff5..8e9b3e3775e 100644
--- a/src/character.c
+++ b/src/character.c
@@ -258,7 +258,8 @@ multibyte_char_to_unibyte_safe (int c)
258} 258}
259 259
260DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0, 260DEFUN ("characterp", Fcharacterp, Scharacterp, 1, 2, 0,
261 doc: /* Return non-nil if OBJECT is a character. */) 261 doc: /* Return non-nil if OBJECT is a character.
262usage: (characterp OBJECT) */)
262 (Lisp_Object object, Lisp_Object ignore) 263 (Lisp_Object object, Lisp_Object ignore)
263{ 264{
264 return (CHARACTERP (object) ? Qt : Qnil); 265 return (CHARACTERP (object) ? Qt : Qnil);
diff --git a/src/character.h b/src/character.h
index 3bc21ac0f2b..063b5147dc9 100644
--- a/src/character.h
+++ b/src/character.h
@@ -597,6 +597,45 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
597 : (c) <= 0xDFFF ? 2 \ 597 : (c) <= 0xDFFF ? 2 \
598 : 0) 598 : 0)
599 599
600/* Data type for Unicode general category.
601
602 The order of members must be in sync with the 8th element of the
603 member of unidata-prop-alist (in admin/unidata/unidata-getn.el) for
604 Unicode character property `general-category'. */
605
606typedef enum {
607 UNICODE_CATEGORY_UNKNOWN = 0,
608 UNICODE_CATEGORY_Lu,
609 UNICODE_CATEGORY_Ll,
610 UNICODE_CATEGORY_Lt,
611 UNICODE_CATEGORY_Lm,
612 UNICODE_CATEGORY_Lo,
613 UNICODE_CATEGORY_Mn,
614 UNICODE_CATEGORY_Mc,
615 UNICODE_CATEGORY_Me,
616 UNICODE_CATEGORY_Nd,
617 UNICODE_CATEGORY_Nl,
618 UNICODE_CATEGORY_No,
619 UNICODE_CATEGORY_Pc,
620 UNICODE_CATEGORY_Pd,
621 UNICODE_CATEGORY_Ps,
622 UNICODE_CATEGORY_Pe,
623 UNICODE_CATEGORY_Pi,
624 UNICODE_CATEGORY_Pf,
625 UNICODE_CATEGORY_Po,
626 UNICODE_CATEGORY_Sm,
627 UNICODE_CATEGORY_Sc,
628 UNICODE_CATEGORY_Sk,
629 UNICODE_CATEGORY_So,
630 UNICODE_CATEGORY_Zs,
631 UNICODE_CATEGORY_Zl,
632 UNICODE_CATEGORY_Zp,
633 UNICODE_CATEGORY_Cc,
634 UNICODE_CATEGORY_Cf,
635 UNICODE_CATEGORY_Cs,
636 UNICODE_CATEGORY_Co,
637 UNICODE_CATEGORY_Cn
638} unicode_category_t;
600 639
601extern int char_resolve_modifier_mask (int); 640extern int char_resolve_modifier_mask (int);
602extern int char_string (unsigned, unsigned char *); 641extern int char_string (unsigned, unsigned char *);
diff --git a/src/chartab.c b/src/chartab.c
index ed5b238646e..efe23eca83f 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -53,7 +53,38 @@ static const int chartab_bits[4] =
53#define CHARTAB_IDX(c, depth, min_char) \ 53#define CHARTAB_IDX(c, depth, min_char) \
54 (((c) - (min_char)) >> chartab_bits[(depth)]) 54 (((c) - (min_char)) >> chartab_bits[(depth)])
55 55
56
57/* Preamble for uniprop (Unicode character property) tables. See the
58 comment of "Unicode character property tables". */
59
60/* Purpose of uniprop tables. */
61static Lisp_Object Qchar_code_property_table;
62
63/* Types of decoder and encoder functions for uniprop values. */
64typedef Lisp_Object (*uniprop_decoder_t) (Lisp_Object, Lisp_Object);
65typedef Lisp_Object (*uniprop_encoder_t) (Lisp_Object, Lisp_Object);
66
67static Lisp_Object uniprop_table_uncompress (Lisp_Object, int);
68static uniprop_decoder_t uniprop_get_decoder (Lisp_Object);
69
70/* 1 iff TABLE is a uniprop table. */
71#define UNIPROP_TABLE_P(TABLE) \
72 (EQ (XCHAR_TABLE (TABLE)->purpose, Qchar_code_property_table) \
73 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (TABLE)) == 5)
56 74
75/* Return a decoder for values in the uniprop table TABLE. */
76#define UNIPROP_GET_DECODER(TABLE) \
77 (UNIPROP_TABLE_P (TABLE) ? uniprop_get_decoder (TABLE) : NULL)
78
79/* Nonzero iff OBJ is a string representing uniprop values of 128
80 succeeding characters (the bottom level of a char-table) by a
81 compressed format. We are sure that no property value has a string
82 starting with '\001' nor '\002'. */
83#define UNIPROP_COMPRESSED_FORM_P(OBJ) \
84 (STRINGP (OBJ) && SCHARS (OBJ) > 0 \
85 && ((SREF (OBJ, 0) == 1 || (SREF (OBJ, 0) == 2))))
86
87
57DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0, 88DEFUN ("make-char-table", Fmake_char_table, Smake_char_table, 1, 2, 0,
58 doc: /* Return a newly created char-table, with purpose PURPOSE. 89 doc: /* Return a newly created char-table, with purpose PURPOSE.
59Each element is initialized to INIT, which defaults to nil. 90Each element is initialized to INIT, which defaults to nil.
@@ -107,7 +138,7 @@ make_sub_char_table (int depth, int min_char, Lisp_Object defalt)
107static Lisp_Object 138static Lisp_Object
108char_table_ascii (Lisp_Object table) 139char_table_ascii (Lisp_Object table)
109{ 140{
110 Lisp_Object sub; 141 Lisp_Object sub, val;
111 142
112 sub = XCHAR_TABLE (table)->contents[0]; 143 sub = XCHAR_TABLE (table)->contents[0];
113 if (! SUB_CHAR_TABLE_P (sub)) 144 if (! SUB_CHAR_TABLE_P (sub))
@@ -115,7 +146,10 @@ char_table_ascii (Lisp_Object table)
115 sub = XSUB_CHAR_TABLE (sub)->contents[0]; 146 sub = XSUB_CHAR_TABLE (sub)->contents[0];
116 if (! SUB_CHAR_TABLE_P (sub)) 147 if (! SUB_CHAR_TABLE_P (sub))
117 return sub; 148 return sub;
118 return XSUB_CHAR_TABLE (sub)->contents[0]; 149 val = XSUB_CHAR_TABLE (sub)->contents[0];
150 if (UNIPROP_TABLE_P (table) && UNIPROP_COMPRESSED_FORM_P (val))
151 val = uniprop_table_uncompress (sub, 0);
152 return val;
119} 153}
120 154
121static Lisp_Object 155static Lisp_Object
@@ -169,16 +203,19 @@ copy_char_table (Lisp_Object table)
169} 203}
170 204
171static Lisp_Object 205static Lisp_Object
172sub_char_table_ref (Lisp_Object table, int c) 206sub_char_table_ref (Lisp_Object table, int c, int is_uniprop)
173{ 207{
174 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); 208 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
175 int depth = XINT (tbl->depth); 209 int depth = XINT (tbl->depth);
176 int min_char = XINT (tbl->min_char); 210 int min_char = XINT (tbl->min_char);
177 Lisp_Object val; 211 Lisp_Object val;
212 int idx = CHARTAB_IDX (c, depth, min_char);
178 213
179 val = tbl->contents[CHARTAB_IDX (c, depth, min_char)]; 214 val = tbl->contents[idx];
215 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val))
216 val = uniprop_table_uncompress (table, idx);
180 if (SUB_CHAR_TABLE_P (val)) 217 if (SUB_CHAR_TABLE_P (val))
181 val = sub_char_table_ref (val, c); 218 val = sub_char_table_ref (val, c, is_uniprop);
182 return val; 219 return val;
183} 220}
184 221
@@ -198,7 +235,7 @@ char_table_ref (Lisp_Object table, int c)
198 { 235 {
199 val = tbl->contents[CHARTAB_IDX (c, 0, 0)]; 236 val = tbl->contents[CHARTAB_IDX (c, 0, 0)];
200 if (SUB_CHAR_TABLE_P (val)) 237 if (SUB_CHAR_TABLE_P (val))
201 val = sub_char_table_ref (val, c); 238 val = sub_char_table_ref (val, c, UNIPROP_TABLE_P (table));
202 } 239 }
203 if (NILP (val)) 240 if (NILP (val))
204 { 241 {
@@ -210,7 +247,8 @@ char_table_ref (Lisp_Object table, int c)
210} 247}
211 248
212static Lisp_Object 249static Lisp_Object
213sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp_Object defalt) 250sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to,
251 Lisp_Object defalt, int is_uniprop)
214{ 252{
215 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); 253 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
216 int depth = XINT (tbl->depth); 254 int depth = XINT (tbl->depth);
@@ -219,8 +257,10 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp
219 Lisp_Object val; 257 Lisp_Object val;
220 258
221 val = tbl->contents[chartab_idx]; 259 val = tbl->contents[chartab_idx];
260 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val))
261 val = uniprop_table_uncompress (table, chartab_idx);
222 if (SUB_CHAR_TABLE_P (val)) 262 if (SUB_CHAR_TABLE_P (val))
223 val = sub_char_table_ref_and_range (val, c, from, to, defalt); 263 val = sub_char_table_ref_and_range (val, c, from, to, defalt, is_uniprop);
224 else if (NILP (val)) 264 else if (NILP (val))
225 val = defalt; 265 val = defalt;
226 266
@@ -232,8 +272,11 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp
232 c = min_char + idx * chartab_chars[depth] - 1; 272 c = min_char + idx * chartab_chars[depth] - 1;
233 idx--; 273 idx--;
234 this_val = tbl->contents[idx]; 274 this_val = tbl->contents[idx];
275 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val))
276 this_val = uniprop_table_uncompress (table, idx);
235 if (SUB_CHAR_TABLE_P (this_val)) 277 if (SUB_CHAR_TABLE_P (this_val))
236 this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt); 278 this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt,
279 is_uniprop);
237 else if (NILP (this_val)) 280 else if (NILP (this_val))
238 this_val = defalt; 281 this_val = defalt;
239 282
@@ -251,8 +294,11 @@ sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp
251 294
252 chartab_idx++; 295 chartab_idx++;
253 this_val = tbl->contents[chartab_idx]; 296 this_val = tbl->contents[chartab_idx];
297 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val))
298 this_val = uniprop_table_uncompress (table, chartab_idx);
254 if (SUB_CHAR_TABLE_P (this_val)) 299 if (SUB_CHAR_TABLE_P (this_val))
255 this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt); 300 this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt,
301 is_uniprop);
256 else if (NILP (this_val)) 302 else if (NILP (this_val))
257 this_val = defalt; 303 this_val = defalt;
258 if (! EQ (this_val, val)) 304 if (! EQ (this_val, val))
@@ -277,17 +323,20 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to)
277 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); 323 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
278 int chartab_idx = CHARTAB_IDX (c, 0, 0), idx; 324 int chartab_idx = CHARTAB_IDX (c, 0, 0), idx;
279 Lisp_Object val; 325 Lisp_Object val;
326 int is_uniprop = UNIPROP_TABLE_P (table);
280 327
281 val = tbl->contents[chartab_idx]; 328 val = tbl->contents[chartab_idx];
282 if (*from < 0) 329 if (*from < 0)
283 *from = 0; 330 *from = 0;
284 if (*to < 0) 331 if (*to < 0)
285 *to = MAX_CHAR; 332 *to = MAX_CHAR;
333 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (val))
334 val = uniprop_table_uncompress (table, chartab_idx);
286 if (SUB_CHAR_TABLE_P (val)) 335 if (SUB_CHAR_TABLE_P (val))
287 val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt); 336 val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt,
337 is_uniprop);
288 else if (NILP (val)) 338 else if (NILP (val))
289 val = tbl->defalt; 339 val = tbl->defalt;
290
291 idx = chartab_idx; 340 idx = chartab_idx;
292 while (*from < idx * chartab_chars[0]) 341 while (*from < idx * chartab_chars[0])
293 { 342 {
@@ -296,9 +345,11 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to)
296 c = idx * chartab_chars[0] - 1; 345 c = idx * chartab_chars[0] - 1;
297 idx--; 346 idx--;
298 this_val = tbl->contents[idx]; 347 this_val = tbl->contents[idx];
348 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val))
349 this_val = uniprop_table_uncompress (table, idx);
299 if (SUB_CHAR_TABLE_P (this_val)) 350 if (SUB_CHAR_TABLE_P (this_val))
300 this_val = sub_char_table_ref_and_range (this_val, c, from, to, 351 this_val = sub_char_table_ref_and_range (this_val, c, from, to,
301 tbl->defalt); 352 tbl->defalt, is_uniprop);
302 else if (NILP (this_val)) 353 else if (NILP (this_val))
303 this_val = tbl->defalt; 354 this_val = tbl->defalt;
304 355
@@ -315,9 +366,11 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to)
315 chartab_idx++; 366 chartab_idx++;
316 c = chartab_idx * chartab_chars[0]; 367 c = chartab_idx * chartab_chars[0];
317 this_val = tbl->contents[chartab_idx]; 368 this_val = tbl->contents[chartab_idx];
369 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this_val))
370 this_val = uniprop_table_uncompress (table, chartab_idx);
318 if (SUB_CHAR_TABLE_P (this_val)) 371 if (SUB_CHAR_TABLE_P (this_val))
319 this_val = sub_char_table_ref_and_range (this_val, c, from, to, 372 this_val = sub_char_table_ref_and_range (this_val, c, from, to,
320 tbl->defalt); 373 tbl->defalt, is_uniprop);
321 else if (NILP (this_val)) 374 else if (NILP (this_val))
322 this_val = tbl->defalt; 375 this_val = tbl->defalt;
323 if (! EQ (this_val, val)) 376 if (! EQ (this_val, val))
@@ -332,7 +385,7 @@ char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to)
332 385
333 386
334static void 387static void
335sub_char_table_set (Lisp_Object table, int c, Lisp_Object val) 388sub_char_table_set (Lisp_Object table, int c, Lisp_Object val, int is_uniprop)
336{ 389{
337 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); 390 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
338 int depth = XINT ((tbl)->depth); 391 int depth = XINT ((tbl)->depth);
@@ -347,11 +400,17 @@ sub_char_table_set (Lisp_Object table, int c, Lisp_Object val)
347 sub = tbl->contents[i]; 400 sub = tbl->contents[i];
348 if (! SUB_CHAR_TABLE_P (sub)) 401 if (! SUB_CHAR_TABLE_P (sub))
349 { 402 {
350 sub = make_sub_char_table (depth + 1, 403 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (sub))
351 min_char + i * chartab_chars[depth], sub); 404 sub = uniprop_table_uncompress (table, i);
352 tbl->contents[i] = sub; 405 else
406 {
407 sub = make_sub_char_table (depth + 1,
408 min_char + i * chartab_chars[depth],
409 sub);
410 tbl->contents[i] = sub;
411 }
353 } 412 }
354 sub_char_table_set (sub, c, val); 413 sub_char_table_set (sub, c, val, is_uniprop);
355 } 414 }
356} 415}
357 416
@@ -376,7 +435,7 @@ char_table_set (Lisp_Object table, int c, Lisp_Object val)
376 sub = make_sub_char_table (1, i * chartab_chars[0], sub); 435 sub = make_sub_char_table (1, i * chartab_chars[0], sub);
377 tbl->contents[i] = sub; 436 tbl->contents[i] = sub;
378 } 437 }
379 sub_char_table_set (sub, c, val); 438 sub_char_table_set (sub, c, val, UNIPROP_TABLE_P (table));
380 if (ASCII_CHAR_P (c)) 439 if (ASCII_CHAR_P (c))
381 tbl->ascii = char_table_ascii (table); 440 tbl->ascii = char_table_ascii (table);
382 } 441 }
@@ -384,30 +443,40 @@ char_table_set (Lisp_Object table, int c, Lisp_Object val)
384} 443}
385 444
386static void 445static void
387sub_char_table_set_range (Lisp_Object *table, int depth, int min_char, int from, int to, Lisp_Object val) 446sub_char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val,
447 int is_uniprop)
388{ 448{
389 int max_char = min_char + chartab_chars[depth] - 1; 449 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
390 450 int depth = XINT ((tbl)->depth);
391 if (depth == 3 || (from <= min_char && to >= max_char)) 451 int min_char = XINT ((tbl)->min_char);
392 *table = val; 452 int chars_in_block = chartab_chars[depth];
393 else 453 int i, c, lim = chartab_size[depth];
454
455 if (from < min_char)
456 from = min_char;
457 i = CHARTAB_IDX (from, depth, min_char);
458 c = min_char + chars_in_block * i;
459 for (; i < lim; i++, c += chars_in_block)
394 { 460 {
395 int i; 461 if (c > to)
396 unsigned j; 462 break;
397 463 if (from <= c && c + chars_in_block - 1 <= to)
398 depth++; 464 tbl->contents[i] = val;
399 if (! SUB_CHAR_TABLE_P (*table)) 465 else
400 *table = make_sub_char_table (depth, min_char, *table); 466 {
401 if (from < min_char) 467 Lisp_Object sub = tbl->contents[i];
402 from = min_char; 468 if (! SUB_CHAR_TABLE_P (sub))
403 if (to > max_char) 469 {
404 to = max_char; 470 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (sub))
405 i = CHARTAB_IDX (from, depth, min_char); 471 sub = uniprop_table_uncompress (table, i);
406 j = CHARTAB_IDX (to, depth, min_char); 472 else
407 min_char += chartab_chars[depth] * i; 473 {
408 for (j++; i < j; i++, min_char += chartab_chars[depth]) 474 sub = make_sub_char_table (depth + 1, c, sub);
409 sub_char_table_set_range (XSUB_CHAR_TABLE (*table)->contents + i, 475 tbl->contents[i] = sub;
410 depth, min_char, from, to, val); 476 }
477 }
478 sub_char_table_set_range (sub, from, to, val, is_uniprop);
479 }
411 } 480 }
412} 481}
413 482
@@ -416,17 +485,33 @@ Lisp_Object
416char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val) 485char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val)
417{ 486{
418 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table); 487 struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
419 Lisp_Object *contents = tbl->contents;
420 int i;
421 488
422 if (from == to) 489 if (from == to)
423 char_table_set (table, from, val); 490 char_table_set (table, from, val);
424 else 491 else
425 { 492 {
426 unsigned lim = to / chartab_chars[0] + 1; 493 int is_uniprop = UNIPROP_TABLE_P (table);
427 for (i = CHARTAB_IDX (from, 0, 0); i < lim; i++) 494 int lim = CHARTAB_IDX (to, 0, 0);
428 sub_char_table_set_range (contents + i, 0, i * chartab_chars[0], 495 int i, c;
429 from, to, val); 496
497 for (i = CHARTAB_IDX (from, 0, 0), c = 0; i <= lim;
498 i++, c += chartab_chars[0])
499 {
500 if (c > to)
501 break;
502 if (from <= c && c + chartab_chars[0] - 1 <= to)
503 tbl->contents[i] = val;
504 else
505 {
506 Lisp_Object sub = tbl->contents[i];
507 if (! SUB_CHAR_TABLE_P (sub))
508 {
509 sub = make_sub_char_table (1, i * chartab_chars[0], sub);
510 tbl->contents[i] = sub;
511 }
512 sub_char_table_set_range (sub, from, to, val, is_uniprop);
513 }
514 }
430 if (ASCII_CHAR_P (from)) 515 if (ASCII_CHAR_P (from))
431 tbl->ascii = char_table_ascii (table); 516 tbl->ascii = char_table_ascii (table);
432 } 517 }
@@ -504,6 +589,8 @@ DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
504 (Lisp_Object char_table, Lisp_Object n, Lisp_Object value) 589 (Lisp_Object char_table, Lisp_Object n, Lisp_Object value)
505{ 590{
506 CHECK_CHAR_TABLE (char_table); 591 CHECK_CHAR_TABLE (char_table);
592 if (EQ (XCHAR_TABLE (char_table)->purpose, Qchar_code_property_table))
593 error ("Can't change extra-slot of char-code-property-table");
507 CHECK_NUMBER (n); 594 CHECK_NUMBER (n);
508 if (XINT (n) < 0 595 if (XINT (n) < 0
509 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table))) 596 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
@@ -532,8 +619,9 @@ a cons of character codes (for characters in the range), or a character code. *
532 619
533 CHECK_CHARACTER_CAR (range); 620 CHECK_CHARACTER_CAR (range);
534 CHECK_CHARACTER_CDR (range); 621 CHECK_CHARACTER_CDR (range);
535 val = char_table_ref_and_range (char_table, XFASTINT (XCAR (range)), 622 from = XFASTINT (XCAR (range));
536 &from, &to); 623 to = XFASTINT (XCDR (range));
624 val = char_table_ref_and_range (char_table, from, &from, &to);
537 /* Not yet implemented. */ 625 /* Not yet implemented. */
538 } 626 }
539 else 627 else
@@ -655,8 +743,7 @@ equivalent and can be merged. It defaults to `equal'. */)
655/* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table), 743/* Map C_FUNCTION or FUNCTION over TABLE (top or sub char-table),
656 calling it for each character or group of characters that share a 744 calling it for each character or group of characters that share a
657 value. RANGE is a cons (FROM . TO) specifying the range of target 745 value. RANGE is a cons (FROM . TO) specifying the range of target
658 characters, VAL is a value of FROM in TABLE, DEFAULT_VAL is the 746 characters, VAL is a value of FROM in TABLE, TOP is the top
659 default value of the char-table, PARENT is the parent of the
660 char-table. 747 char-table.
661 748
662 ARG is passed to C_FUNCTION when that is called. 749 ARG is passed to C_FUNCTION when that is called.
@@ -669,10 +756,8 @@ equivalent and can be merged. It defaults to `equal'. */)
669static Lisp_Object 756static Lisp_Object
670map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), 757map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
671 Lisp_Object function, Lisp_Object table, Lisp_Object arg, Lisp_Object val, 758 Lisp_Object function, Lisp_Object table, Lisp_Object arg, Lisp_Object val,
672 Lisp_Object range, Lisp_Object default_val, Lisp_Object parent) 759 Lisp_Object range, Lisp_Object top)
673{ 760{
674 /* Pointer to the elements of TABLE. */
675 Lisp_Object *contents;
676 /* Depth of TABLE. */ 761 /* Depth of TABLE. */
677 int depth; 762 int depth;
678 /* Minimum and maxinum characters covered by TABLE. */ 763 /* Minimum and maxinum characters covered by TABLE. */
@@ -681,20 +766,20 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
681 int chars_in_block; 766 int chars_in_block;
682 int from = XINT (XCAR (range)), to = XINT (XCDR (range)); 767 int from = XINT (XCAR (range)), to = XINT (XCDR (range));
683 int i, c; 768 int i, c;
769 int is_uniprop = UNIPROP_TABLE_P (top);
770 uniprop_decoder_t decoder = UNIPROP_GET_DECODER (top);
684 771
685 if (SUB_CHAR_TABLE_P (table)) 772 if (SUB_CHAR_TABLE_P (table))
686 { 773 {
687 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table); 774 struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
688 775
689 depth = XINT (tbl->depth); 776 depth = XINT (tbl->depth);
690 contents = tbl->contents;
691 min_char = XINT (tbl->min_char); 777 min_char = XINT (tbl->min_char);
692 max_char = min_char + chartab_chars[depth - 1] - 1; 778 max_char = min_char + chartab_chars[depth - 1] - 1;
693 } 779 }
694 else 780 else
695 { 781 {
696 depth = 0; 782 depth = 0;
697 contents = XCHAR_TABLE (table)->contents;
698 min_char = 0; 783 min_char = 0;
699 max_char = MAX_CHAR; 784 max_char = MAX_CHAR;
700 } 785 }
@@ -710,28 +795,33 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
710 for (c = min_char + chars_in_block * i; c <= max_char; 795 for (c = min_char + chars_in_block * i; c <= max_char;
711 i++, c += chars_in_block) 796 i++, c += chars_in_block)
712 { 797 {
713 Lisp_Object this = contents[i]; 798 Lisp_Object this = (SUB_CHAR_TABLE_P (table)
799 ? XSUB_CHAR_TABLE (table)->contents[i]
800 : XCHAR_TABLE (table)->contents[i]);
714 int nextc = c + chars_in_block; 801 int nextc = c + chars_in_block;
715 802
803 if (is_uniprop && UNIPROP_COMPRESSED_FORM_P (this))
804 this = uniprop_table_uncompress (table, i);
716 if (SUB_CHAR_TABLE_P (this)) 805 if (SUB_CHAR_TABLE_P (this))
717 { 806 {
718 if (to >= nextc) 807 if (to >= nextc)
719 XSETCDR (range, make_number (nextc - 1)); 808 XSETCDR (range, make_number (nextc - 1));
720 val = map_sub_char_table (c_function, function, this, arg, 809 val = map_sub_char_table (c_function, function, this, arg,
721 val, range, default_val, parent); 810 val, range, top);
722 } 811 }
723 else 812 else
724 { 813 {
725 if (NILP (this)) 814 if (NILP (this))
726 this = default_val; 815 this = XCHAR_TABLE (top)->defalt;
727 if (!EQ (val, this)) 816 if (!EQ (val, this))
728 { 817 {
729 int different_value = 1; 818 int different_value = 1;
730 819
731 if (NILP (val)) 820 if (NILP (val))
732 { 821 {
733 if (! NILP (parent)) 822 if (! NILP (XCHAR_TABLE (top)->parent))
734 { 823 {
824 Lisp_Object parent = XCHAR_TABLE (top)->parent;
735 Lisp_Object temp = XCHAR_TABLE (parent)->parent; 825 Lisp_Object temp = XCHAR_TABLE (parent)->parent;
736 826
737 /* This is to get a value of FROM in PARENT 827 /* This is to get a value of FROM in PARENT
@@ -742,8 +832,7 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
742 XSETCDR (range, make_number (c - 1)); 832 XSETCDR (range, make_number (c - 1));
743 val = map_sub_char_table (c_function, function, 833 val = map_sub_char_table (c_function, function,
744 parent, arg, val, range, 834 parent, arg, val, range,
745 XCHAR_TABLE (parent)->defalt, 835 parent);
746 XCHAR_TABLE (parent)->parent);
747 if (EQ (val, this)) 836 if (EQ (val, this))
748 different_value = 0; 837 different_value = 0;
749 } 838 }
@@ -756,14 +845,22 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
756 if (c_function) 845 if (c_function)
757 (*c_function) (arg, XCAR (range), val); 846 (*c_function) (arg, XCAR (range), val);
758 else 847 else
759 call2 (function, XCAR (range), val); 848 {
849 if (decoder)
850 val = decoder (top, val);
851 call2 (function, XCAR (range), val);
852 }
760 } 853 }
761 else 854 else
762 { 855 {
763 if (c_function) 856 if (c_function)
764 (*c_function) (arg, range, val); 857 (*c_function) (arg, range, val);
765 else 858 else
766 call2 (function, range, val); 859 {
860 if (decoder)
861 val = decoder (top, val);
862 call2 (function, range, val);
863 }
767 } 864 }
768 } 865 }
769 val = this; 866 val = this;
@@ -783,35 +880,39 @@ map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
783 ARG is passed to C_FUNCTION when that is called. */ 880 ARG is passed to C_FUNCTION when that is called. */
784 881
785void 882void
786map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object function, Lisp_Object table, Lisp_Object arg) 883map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
884 Lisp_Object function, Lisp_Object table, Lisp_Object arg)
787{ 885{
788 Lisp_Object range, val; 886 Lisp_Object range, val, parent;
789 struct gcpro gcpro1, gcpro2, gcpro3; 887 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
888 uniprop_decoder_t decoder = UNIPROP_GET_DECODER (table);
790 889
791 range = Fcons (make_number (0), make_number (MAX_CHAR)); 890 range = Fcons (make_number (0), make_number (MAX_CHAR));
792 GCPRO3 (table, arg, range); 891 parent = XCHAR_TABLE (table)->parent;
892
893 GCPRO4 (table, arg, range, parent);
793 val = XCHAR_TABLE (table)->ascii; 894 val = XCHAR_TABLE (table)->ascii;
794 if (SUB_CHAR_TABLE_P (val)) 895 if (SUB_CHAR_TABLE_P (val))
795 val = XSUB_CHAR_TABLE (val)->contents[0]; 896 val = XSUB_CHAR_TABLE (val)->contents[0];
796 val = map_sub_char_table (c_function, function, table, arg, val, range, 897 val = map_sub_char_table (c_function, function, table, arg, val, range,
797 XCHAR_TABLE (table)->defalt, 898 table);
798 XCHAR_TABLE (table)->parent); 899
799 /* If VAL is nil and TABLE has a parent, we must consult the parent 900 /* If VAL is nil and TABLE has a parent, we must consult the parent
800 recursively. */ 901 recursively. */
801 while (NILP (val) && ! NILP (XCHAR_TABLE (table)->parent)) 902 while (NILP (val) && ! NILP (XCHAR_TABLE (table)->parent))
802 { 903 {
803 Lisp_Object parent = XCHAR_TABLE (table)->parent; 904 Lisp_Object temp;
804 Lisp_Object temp = XCHAR_TABLE (parent)->parent;
805 int from = XINT (XCAR (range)); 905 int from = XINT (XCAR (range));
806 906
907 parent = XCHAR_TABLE (table)->parent;
908 temp = XCHAR_TABLE (parent)->parent;
807 /* This is to get a value of FROM in PARENT without checking the 909 /* This is to get a value of FROM in PARENT without checking the
808 parent of PARENT. */ 910 parent of PARENT. */
809 XCHAR_TABLE (parent)->parent = Qnil; 911 XCHAR_TABLE (parent)->parent = Qnil;
810 val = CHAR_TABLE_REF (parent, from); 912 val = CHAR_TABLE_REF (parent, from);
811 XCHAR_TABLE (parent)->parent = temp; 913 XCHAR_TABLE (parent)->parent = temp;
812 val = map_sub_char_table (c_function, function, parent, arg, val, range, 914 val = map_sub_char_table (c_function, function, parent, arg, val, range,
813 XCHAR_TABLE (parent)->defalt, 915 parent);
814 XCHAR_TABLE (parent)->parent);
815 table = parent; 916 table = parent;
816 } 917 }
817 918
@@ -822,14 +923,22 @@ map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp
822 if (c_function) 923 if (c_function)
823 (*c_function) (arg, XCAR (range), val); 924 (*c_function) (arg, XCAR (range), val);
824 else 925 else
825 call2 (function, XCAR (range), val); 926 {
927 if (decoder)
928 val = decoder (table, val);
929 call2 (function, XCAR (range), val);
930 }
826 } 931 }
827 else 932 else
828 { 933 {
829 if (c_function) 934 if (c_function)
830 (*c_function) (arg, range, val); 935 (*c_function) (arg, range, val);
831 else 936 else
832 call2 (function, range, val); 937 {
938 if (decoder)
939 val = decoder (table, val);
940 call2 (function, range, val);
941 }
833 } 942 }
834 } 943 }
835 944
@@ -984,9 +1093,314 @@ map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
984} 1093}
985 1094
986 1095
1096/* Unicode character property tables.
1097
1098 This section provides a convenient and efficient way to get a
1099 Unicode character property from C code (from Lisp, you must use
1100 get-char-code-property).
1101
1102 The typical usage is to get a char-table for a specific property at
1103 a proper initialization time as this:
1104
1105 Lisp_Object bidi_class_table = uniprop_table (intern ("bidi-class"));
1106
1107 and get a property value for character CH as this:
1108
1109 Lisp_Object bidi_class = CHAR_TABLE_REF (CH, bidi_class_table);
1110
1111 In this case, what you actually get is an index number to the
1112 vector of property values (symbols nil, L, R, etc).
1113
1114 A table for Unicode character property has these characteristics:
1115
1116 o The purpose is `char-code-property-table', which implies that the
1117 table has 5 extra slots.
1118
1119 o The second extra slot is a Lisp function, an index (integer) to
1120 the array uniprop_decoder[], or nil. If it is a Lisp function, we
1121 can't use such a table from C (at the moment). If it is nil, it
1122 means that we don't have to decode values.
1123
1124 o The third extra slot is a Lisp function, an index (integer) to
1125 the array uniprop_enncoder[], or nil. If it is a Lisp function, we
1126 can't use such a table from C (at the moment). If it is nil, it
1127 means that we don't have to encode values. */
1128
1129
1130/* Uncompress the IDXth element of sub-char-table TABLE. */
1131
1132static Lisp_Object
1133uniprop_table_uncompress (Lisp_Object table, int idx)
1134{
1135 Lisp_Object val = XSUB_CHAR_TABLE (table)->contents[idx];
1136 int min_char = (XINT (XSUB_CHAR_TABLE (table)->min_char)
1137 + chartab_chars[2] * idx);
1138 Lisp_Object sub = make_sub_char_table (3, min_char, Qnil);
1139 struct Lisp_Sub_Char_Table *subtbl = XSUB_CHAR_TABLE (sub);
1140 const unsigned char *p, *pend;
1141
1142 XSUB_CHAR_TABLE (table)->contents[idx] = sub;
1143 p = SDATA (val), pend = p + SBYTES (val);
1144 if (*p == 1)
1145 {
1146 /* SIMPLE TABLE */
1147 p++;
1148 idx = STRING_CHAR_ADVANCE (p);
1149 while (p < pend && idx < chartab_chars[2])
1150 {
1151 int v = STRING_CHAR_ADVANCE (p);
1152 subtbl->contents[idx++] = v > 0 ? make_number (v) : Qnil;
1153 }
1154 }
1155 else if (*p == 2)
1156 {
1157 /* RUN-LENGTH TABLE */
1158 p++;
1159 for (idx = 0; p < pend; )
1160 {
1161 int v = STRING_CHAR_ADVANCE (p);
1162 int count = 1;
1163 int len;
1164
1165 if (p < pend)
1166 {
1167 count = STRING_CHAR_AND_LENGTH (p, len);
1168 if (count < 128)
1169 count = 1;
1170 else
1171 {
1172 count -= 128;
1173 p += len;
1174 }
1175 }
1176 while (count-- > 0)
1177 subtbl->contents[idx++] = make_number (v);
1178 }
1179 }
1180/* It seems that we don't need this function because C code won't need
1181 to get a property that is compressed in this form. */
1182#if 0
1183 else if (*p == 0)
1184 {
1185 /* WORD-LIST TABLE */
1186 }
1187#endif
1188 return sub;
1189}
1190
1191
1192/* Decode VALUE as an elemnet of char-table TABLE. */
1193
1194static Lisp_Object
1195uniprop_decode_value_run_length (Lisp_Object table, Lisp_Object value)
1196{
1197 if (VECTORP (XCHAR_TABLE (table)->extras[4]))
1198 {
1199 Lisp_Object valvec = XCHAR_TABLE (table)->extras[4];
1200
1201 if (XINT (value) >= 0 && XINT (value) < ASIZE (valvec))
1202 value = AREF (valvec, XINT (value));
1203 }
1204 return value;
1205}
1206
1207static uniprop_decoder_t uniprop_decoder [] =
1208 { uniprop_decode_value_run_length };
1209
1210static int uniprop_decoder_count
1211 = (sizeof uniprop_decoder) / sizeof (uniprop_decoder[0]);
1212
1213
1214/* Return the decoder of char-table TABLE or nil if none. */
1215
1216static uniprop_decoder_t
1217uniprop_get_decoder (Lisp_Object table)
1218{
1219 int i;
1220
1221 if (! INTEGERP (XCHAR_TABLE (table)->extras[1]))
1222 return NULL;
1223 i = XINT (XCHAR_TABLE (table)->extras[1]);
1224 if (i < 0 || i >= uniprop_decoder_count)
1225 return NULL;
1226 return uniprop_decoder[i];
1227}
1228
1229
1230/* Encode VALUE as an element of char-table TABLE which contains
1231 characters as elements. */
1232
1233static Lisp_Object
1234uniprop_encode_value_character (Lisp_Object table, Lisp_Object value)
1235{
1236 if (! NILP (value) && ! CHARACTERP (value))
1237 wrong_type_argument (Qintegerp, value);
1238 return value;
1239}
1240
1241
1242/* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1243 compression. */
1244
1245static Lisp_Object
1246uniprop_encode_value_run_length (Lisp_Object table, Lisp_Object value)
1247{
1248 Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents;
1249 int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]);
1250
1251 for (i = 0; i < size; i++)
1252 if (EQ (value, value_table[i]))
1253 break;
1254 if (i == size)
1255 wrong_type_argument (build_string ("Unicode property value"), value);
1256 return make_number (i);
1257}
1258
1259
1260/* Encode VALUE as an element of char-table TABLE which adopts RUN-LENGTH
1261 compression and contains numbers as elements . */
1262
1263static Lisp_Object
1264uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value)
1265{
1266 Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents;
1267 int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]);
1268
1269 CHECK_NUMBER (value);
1270 for (i = 0; i < size; i++)
1271 if (EQ (value, value_table[i]))
1272 break;
1273 value = make_number (i);
1274 if (i == size)
1275 {
1276 Lisp_Object args[2];
1277
1278 args[0] = XCHAR_TABLE (table)->extras[4];
1279 args[1] = Fmake_vector (make_number (1), value);
1280 XCHAR_TABLE (table)->extras[4] = Fvconcat (2, args);
1281 }
1282 return make_number (i);
1283}
1284
1285static uniprop_encoder_t uniprop_encoder[] =
1286 { uniprop_encode_value_character,
1287 uniprop_encode_value_run_length,
1288 uniprop_encode_value_numeric };
1289
1290static int uniprop_encoder_count
1291 = (sizeof uniprop_encoder) / sizeof (uniprop_encoder[0]);
1292
1293
1294/* Return the encoder of char-table TABLE or nil if none. */
1295
1296static uniprop_decoder_t
1297uniprop_get_encoder (Lisp_Object table)
1298{
1299 int i;
1300
1301 if (! INTEGERP (XCHAR_TABLE (table)->extras[2]))
1302 return NULL;
1303 i = XINT (XCHAR_TABLE (table)->extras[2]);
1304 if (i < 0 || i >= uniprop_encoder_count)
1305 return NULL;
1306 return uniprop_encoder[i];
1307}
1308
1309/* Return a char-table for Unicode character property PROP. This
1310 function may load a Lisp file and thus may cause
1311 garbage-collection. */
1312
1313static Lisp_Object
1314uniprop_table (Lisp_Object prop)
1315{
1316 Lisp_Object val, table, result;
1317
1318 val = Fassq (prop, Vchar_code_property_alist);
1319 if (! CONSP (val))
1320 return Qnil;
1321 table = XCDR (val);
1322 if (STRINGP (table))
1323 {
1324 struct gcpro gcpro1;
1325 GCPRO1 (val);
1326 result = Fload (concat2 (build_string ("international/"), table),
1327 Qt, Qt, Qt, Qt);
1328 UNGCPRO;
1329 if (NILP (result))
1330 return Qnil;
1331 table = XCDR (val);
1332 }
1333 if (! CHAR_TABLE_P (table)
1334 || ! UNIPROP_TABLE_P (table))
1335 return Qnil;
1336 val = XCHAR_TABLE (table)->extras[1];
1337 if (INTEGERP (val)
1338 ? (XINT (val) < 0 || XINT (val) >= uniprop_decoder_count)
1339 : ! NILP (val))
1340 return Qnil;
1341 /* Prepare ASCII values in advance for CHAR_TABLE_REF. */
1342 XCHAR_TABLE (table)->ascii = char_table_ascii (table);
1343 return table;
1344}
1345
1346DEFUN ("unicode-property-table-internal", Funicode_property_table_internal,
1347 Sunicode_property_table_internal, 1, 1, 0,
1348 doc: /* Return a char-table for Unicode character property PROP.
1349Use `get-unicode-property-internal' and
1350`put-unicode-property-internal' instead of `aref' and `aset' to get
1351and put an element value. */)
1352 (Lisp_Object prop)
1353{
1354 Lisp_Object table = uniprop_table (prop);
1355
1356 if (CHAR_TABLE_P (table))
1357 return table;
1358 return Fcdr (Fassq (prop, Vchar_code_property_alist));
1359}
1360
1361DEFUN ("get-unicode-property-internal", Fget_unicode_property_internal,
1362 Sget_unicode_property_internal, 2, 2, 0,
1363 doc: /* Return an element of CHAR-TABLE for character CH.
1364CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
1365 (Lisp_Object char_table, Lisp_Object ch)
1366{
1367 Lisp_Object val;
1368 uniprop_decoder_t decoder;
1369
1370 CHECK_CHAR_TABLE (char_table);
1371 CHECK_CHARACTER (ch);
1372 if (! UNIPROP_TABLE_P (char_table))
1373 error ("Invalid Unicode property table");
1374 val = CHAR_TABLE_REF (char_table, XINT (ch));
1375 decoder = uniprop_get_decoder (char_table);
1376 return (decoder ? decoder (char_table, val) : val);
1377}
1378
1379DEFUN ("put-unicode-property-internal", Fput_unicode_property_internal,
1380 Sput_unicode_property_internal, 3, 3, 0,
1381 doc: /* Set an element of CHAR-TABLE for character CH to VALUE.
1382CHAR-TABLE must be what returned by `unicode-property-table-internal'. */)
1383 (Lisp_Object char_table, Lisp_Object ch, Lisp_Object value)
1384{
1385 uniprop_encoder_t encoder;
1386
1387 CHECK_CHAR_TABLE (char_table);
1388 CHECK_CHARACTER (ch);
1389 if (! UNIPROP_TABLE_P (char_table))
1390 error ("Invalid Unicode property table");
1391 encoder = uniprop_get_encoder (char_table);
1392 if (encoder)
1393 value = encoder (char_table, value);
1394 CHAR_TABLE_SET (char_table, XINT (ch), value);
1395 return Qnil;
1396}
1397
1398
987void 1399void
988syms_of_chartab (void) 1400syms_of_chartab (void)
989{ 1401{
1402 DEFSYM (Qchar_code_property_table, "char-code-property-table");
1403
990 defsubr (&Smake_char_table); 1404 defsubr (&Smake_char_table);
991 defsubr (&Schar_table_parent); 1405 defsubr (&Schar_table_parent);
992 defsubr (&Schar_table_subtype); 1406 defsubr (&Schar_table_subtype);
@@ -998,4 +1412,19 @@ syms_of_chartab (void)
998 defsubr (&Sset_char_table_default); 1412 defsubr (&Sset_char_table_default);
999 defsubr (&Soptimize_char_table); 1413 defsubr (&Soptimize_char_table);
1000 defsubr (&Smap_char_table); 1414 defsubr (&Smap_char_table);
1415 defsubr (&Sunicode_property_table_internal);
1416 defsubr (&Sget_unicode_property_internal);
1417 defsubr (&Sput_unicode_property_internal);
1418
1419 /* Each element has the form (PROP . TABLE).
1420 PROP is a symbol representing a character property.
1421 TABLE is a char-table containing the property value for each character.
1422 TABLE may be a name of file to load to build a char-table.
1423 This variable should be modified only through
1424 `define-char-code-property'. */
1425
1426 DEFVAR_LISP ("char-code-property-alist", Vchar_code_property_alist,
1427 doc: /* Alist of character property name vs char-table containing property values.
1428Internal use only. */);
1429 Vchar_code_property_alist = Qnil;
1001} 1430}
diff --git a/src/cm.c b/src/cm.c
index 42f855f1694..609632eba11 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -305,7 +305,8 @@ done:
305} 305}
306 306
307#if 0 307#if 0
308losecursor () 308void
309losecursor (void)
309{ 310{
310 curY = -1; 311 curY = -1;
311} 312}
diff --git a/src/coding.c b/src/coding.c
index 9939774ea82..65c8a767c2b 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -9000,7 +9000,7 @@ not fully specified.) */)
9000 (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) 9000 (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer)
9001{ 9001{
9002 return code_convert_string (string, coding_system, buffer, 9002 return code_convert_string (string, coding_system, buffer,
9003 1, ! NILP (nocopy), 1); 9003 1, ! NILP (nocopy), 0);
9004} 9004}
9005 9005
9006 9006
diff --git a/src/composite.c b/src/composite.c
index de9775d18f5..d402d5ad0c4 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -967,7 +967,6 @@ autocmp_chars (Lisp_Object rule, EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT
967} 967}
968 968
969static Lisp_Object _work_val; 969static Lisp_Object _work_val;
970static int _work_char;
971 970
972/* 1 iff the character C is composable. Characters of general 971/* 1 iff the character C is composable. Characters of general
973 category Z? or C? are not composable except for ZWNJ and ZWJ. */ 972 category Z? or C? are not composable except for ZWNJ and ZWJ. */
@@ -976,9 +975,8 @@ static int _work_char;
976 ((C) > ' ' \ 975 ((C) > ' ' \
977 && ((C) == 0x200C || (C) == 0x200D \ 976 && ((C) == 0x200C || (C) == 0x200D \
978 || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \ 977 || (_work_val = CHAR_TABLE_REF (Vunicode_category_table, (C)), \
979 (SYMBOLP (_work_val) \ 978 (INTEGERP (_work_val) \
980 && (_work_char = SDATA (SYMBOL_NAME (_work_val))[0]) != 'C' \ 979 && (XINT (_work_val) <= UNICODE_CATEGORY_So)))))
981 && _work_char != 'Z'))))
982 980
983/* Update cmp_it->stop_pos to the next position after CHARPOS (and 981/* Update cmp_it->stop_pos to the next position after CHARPOS (and
984 BYTEPOS) where character composition may happen. If BYTEPOS is 982 BYTEPOS) where character composition may happen. If BYTEPOS is
@@ -1027,6 +1025,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, EMACS_INT charpos,
1027 /* FIXME: Bidi is not yet handled well in static composition. */ 1025 /* FIXME: Bidi is not yet handled well in static composition. */
1028 if (charpos < endpos 1026 if (charpos < endpos
1029 && find_composition (charpos, endpos, &start, &end, &prop, string) 1027 && find_composition (charpos, endpos, &start, &end, &prop, string)
1028 && start >= charpos
1030 && COMPOSITION_VALID_P (start, end, prop)) 1029 && COMPOSITION_VALID_P (start, end, prop))
1031 { 1030 {
1032 cmp_it->stop_pos = endpos = start; 1031 cmp_it->stop_pos = endpos = start;
diff --git a/src/data.c b/src/data.c
index 6b4ea32ac9e..7bc04592c57 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2736,8 +2736,7 @@ Both must be integers or markers. */)
2736 2736
2737#ifndef HAVE_FMOD 2737#ifndef HAVE_FMOD
2738double 2738double
2739fmod (f1, f2) 2739fmod (double f1, double f2)
2740 double f1, f2;
2741{ 2740{
2742 double r = f1; 2741 double r = f1;
2743 2742
diff --git a/src/dispextern.h b/src/dispextern.h
index 31ad7af4a84..ec1bdab815c 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1779,7 +1779,11 @@ extern int face_change_count;
1779/* Data type for describing the bidirectional character types. The 1779/* Data type for describing the bidirectional character types. The
1780 first 7 must be at the beginning, because they are the only values 1780 first 7 must be at the beginning, because they are the only values
1781 valid in the `bidi_type' member of `struct glyph'; we only reserve 1781 valid in the `bidi_type' member of `struct glyph'; we only reserve
1782 3 bits for it, so we cannot use there values larger than 7. */ 1782 3 bits for it, so we cannot use there values larger than 7.
1783
1784 The order of members must be in sync with the 8th element of the
1785 member of unidata-prop-alist (in admin/unidata/unidata-getn.el) for
1786 Unicode character property `bidi-class'. */
1783typedef enum { 1787typedef enum {
1784 UNKNOWN_BT = 0, 1788 UNKNOWN_BT = 0,
1785 STRONG_L, /* strong left-to-right */ 1789 STRONG_L, /* strong left-to-right */
@@ -1822,9 +1826,21 @@ struct bidi_stack {
1822 bidi_dir_t override; 1826 bidi_dir_t override;
1823}; 1827};
1824 1828
1829/* Data type for storing information about a string being iterated on. */
1830struct bidi_string_data {
1831 Lisp_Object lstring; /* Lisp string to reorder, or nil */
1832 const unsigned char *s; /* string data, or NULL if reordering buffer */
1833 EMACS_INT schars; /* the number of characters in the string,
1834 excluding the terminating null */
1835 EMACS_INT bufpos; /* buffer position of lstring, or 0 if N/A */
1836 unsigned from_disp_str : 1; /* 1 means the string comes from a
1837 display property */
1838 unsigned unibyte : 1; /* 1 means the string is unibyte */
1839};
1840
1825/* Data type for reordering bidirectional text. */ 1841/* Data type for reordering bidirectional text. */
1826struct bidi_it { 1842struct bidi_it {
1827 EMACS_INT bytepos; /* iterator's position in buffer */ 1843 EMACS_INT bytepos; /* iterator's position in buffer/string */
1828 EMACS_INT charpos; 1844 EMACS_INT charpos;
1829 int ch; /* character at that position, or u+FFFC 1845 int ch; /* character at that position, or u+FFFC
1830 ("object replacement character") for a run 1846 ("object replacement character") for a run
@@ -1854,12 +1870,13 @@ struct bidi_it {
1854 iterator state is saved, pushed, or popped. So only put here 1870 iterator state is saved, pushed, or popped. So only put here
1855 stuff that is not part of the bidi iterator's state! */ 1871 stuff that is not part of the bidi iterator's state! */
1856 struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */ 1872 struct bidi_stack level_stack[BIDI_MAXLEVEL]; /* stack of embedding levels */
1857 int first_elt; /* if non-zero, examine current char first */ 1873 struct bidi_string_data string; /* string to reorder */
1858 bidi_dir_t paragraph_dir; /* current paragraph direction */ 1874 bidi_dir_t paragraph_dir; /* current paragraph direction */
1859 int new_paragraph; /* if non-zero, we expect a new paragraph */
1860 int frame_window_p; /* non-zero if displaying on a GUI frame */
1861 EMACS_INT separator_limit; /* where paragraph separator should end */ 1875 EMACS_INT separator_limit; /* where paragraph separator should end */
1862 EMACS_INT disp_pos; /* position of display string after ch */ 1876 EMACS_INT disp_pos; /* position of display string after ch */
1877 unsigned first_elt : 1; /* if non-zero, examine current char first */
1878 unsigned new_paragraph : 1; /* if non-zero, we expect a new paragraph */
1879 unsigned frame_window_p : 1; /* non-zero if displaying on a GUI frame */
1863}; 1880};
1864 1881
1865/* Value is non-zero when the bidi iterator is at base paragraph 1882/* Value is non-zero when the bidi iterator is at base paragraph
@@ -2139,6 +2156,10 @@ struct it
2139 Don't handle some `display' properties in these strings. */ 2156 Don't handle some `display' properties in these strings. */
2140 unsigned string_from_display_prop_p : 1; 2157 unsigned string_from_display_prop_p : 1;
2141 2158
2159 /* 1 means we are iterating an object that came from a value of a
2160 `display' property. */
2161 unsigned from_disp_prop_p : 1;
2162
2142 /* When METHOD == next_element_from_display_vector, 2163 /* When METHOD == next_element_from_display_vector,
2143 this is 1 if we're doing an ellipsis. Otherwise meaningless. */ 2164 this is 1 if we're doing an ellipsis. Otherwise meaningless. */
2144 unsigned ellipsis_p : 1; 2165 unsigned ellipsis_p : 1;
@@ -2158,7 +2179,9 @@ struct it
2158 Lisp_Object *dpvec, *dpend; 2179 Lisp_Object *dpvec, *dpend;
2159 2180
2160 /* Length in bytes of the char that filled dpvec. A value of zero 2181 /* Length in bytes of the char that filled dpvec. A value of zero
2161 means that no such character is involved. */ 2182 means that no such character is involved. A negative value means
2183 the rest of the line from the current iterator position onwards
2184 is hidden by selective display or ellipsis. */
2162 int dpvec_char_len; 2185 int dpvec_char_len;
2163 2186
2164 /* Face id to use for all characters in display vector. -1 if unused. */ 2187 /* Face id to use for all characters in display vector. -1 if unused. */
@@ -2256,10 +2279,13 @@ struct it
2256 Lisp_Object from_overlay; 2279 Lisp_Object from_overlay;
2257 enum glyph_row_area area; 2280 enum glyph_row_area area;
2258 enum it_method method; 2281 enum it_method method;
2282 bidi_dir_t paragraph_embedding;
2259 unsigned multibyte_p : 1; 2283 unsigned multibyte_p : 1;
2260 unsigned string_from_display_prop_p : 1; 2284 unsigned string_from_display_prop_p : 1;
2261 unsigned display_ellipsis_p : 1; 2285 unsigned display_ellipsis_p : 1;
2262 unsigned avoid_cursor_p : 1; 2286 unsigned avoid_cursor_p : 1;
2287 unsigned bidi_p:1;
2288 unsigned from_disp_prop_p : 1;
2263 enum line_wrap_method line_wrap; 2289 enum line_wrap_method line_wrap;
2264 2290
2265 /* properties from display property that are reset by another display property. */ 2291 /* properties from display property that are reset by another display property. */
@@ -2484,7 +2510,7 @@ struct it
2484 2510
2485 /* Non-zero means we need to reorder bidirectional text for display 2511 /* Non-zero means we need to reorder bidirectional text for display
2486 in the visual order. */ 2512 in the visual order. */
2487 int bidi_p; 2513 unsigned bidi_p : 1;
2488 2514
2489 /* For iterating over bidirectional text. */ 2515 /* For iterating over bidirectional text. */
2490 struct bidi_it bidi_it; 2516 struct bidi_it bidi_it;
@@ -2966,6 +2992,10 @@ extern void bidi_init_it (EMACS_INT, EMACS_INT, int, struct bidi_it *);
2966extern void bidi_move_to_visually_next (struct bidi_it *); 2992extern void bidi_move_to_visually_next (struct bidi_it *);
2967extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int); 2993extern void bidi_paragraph_init (bidi_dir_t, struct bidi_it *, int);
2968extern int bidi_mirror_char (int); 2994extern int bidi_mirror_char (int);
2995extern void bidi_push_it (struct bidi_it *);
2996extern void bidi_pop_it (struct bidi_it *);
2997extern void *bidi_shelve_cache (void);
2998extern void bidi_unshelve_cache (void *);
2969 2999
2970/* Defined in xdisp.c */ 3000/* Defined in xdisp.c */
2971 3001
@@ -3023,8 +3053,10 @@ extern void reseat_at_previous_visible_line_start (struct it *);
3023extern Lisp_Object lookup_glyphless_char_display (int, struct it *); 3053extern Lisp_Object lookup_glyphless_char_display (int, struct it *);
3024extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object, 3054extern int calc_pixel_width_or_height (double *, struct it *, Lisp_Object,
3025 struct font *, int, int *); 3055 struct font *, int, int *);
3026extern EMACS_INT compute_display_string_pos (EMACS_INT, int); 3056extern EMACS_INT compute_display_string_pos (struct text_pos *,
3027extern EMACS_INT compute_display_string_end (EMACS_INT); 3057 struct bidi_string_data *, int);
3058extern EMACS_INT compute_display_string_end (EMACS_INT,
3059 struct bidi_string_data *);
3028 3060
3029#ifdef HAVE_WINDOW_SYSTEM 3061#ifdef HAVE_WINDOW_SYSTEM
3030 3062
diff --git a/src/dispnew.c b/src/dispnew.c
index bde90d847ce..bfd4b3a7ecf 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -1065,8 +1065,7 @@ increment_row_positions (struct glyph_row *row,
1065 B without changing glyph pointers in A and B. */ 1065 B without changing glyph pointers in A and B. */
1066 1066
1067static void 1067static void
1068swap_glyphs_in_rows (a, b) 1068swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b)
1069 struct glyph_row *a, *b;
1070{ 1069{
1071 int area; 1070 int area;
1072 1071
@@ -5284,10 +5283,12 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5284 struct image *img = 0; 5283 struct image *img = 0;
5285#endif 5284#endif
5286 int x0, x1, to_x; 5285 int x0, x1, to_x;
5286 void *itdata = NULL;
5287 5287
5288 /* We used to set current_buffer directly here, but that does the 5288 /* We used to set current_buffer directly here, but that does the
5289 wrong thing with `face-remapping-alist' (bug#2044). */ 5289 wrong thing with `face-remapping-alist' (bug#2044). */
5290 Fset_buffer (w->buffer); 5290 Fset_buffer (w->buffer);
5291 itdata = bidi_shelve_cache ();
5291 SET_TEXT_POS_FROM_MARKER (startp, w->start); 5292 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5292 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); 5293 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5293 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); 5294 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
@@ -5321,6 +5322,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5321 argument is ZV to prevent move_it_in_display_line from matching 5322 argument is ZV to prevent move_it_in_display_line from matching
5322 based on buffer positions. */ 5323 based on buffer positions. */
5323 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); 5324 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
5325 bidi_unshelve_cache (itdata);
5324 5326
5325 Fset_buffer (old_current_buffer); 5327 Fset_buffer (old_current_buffer);
5326 5328
diff --git a/src/editfns.c b/src/editfns.c
index 5328b714b0f..b20c38faacd 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -194,8 +194,12 @@ DEFUN ("byte-to-string", Fbyte_to_string, Sbyte_to_string, 1, 1, 0,
194} 194}
195 195
196DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0, 196DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
197 doc: /* Convert arg STRING to a character, the first character of that string. 197 doc: /* Return the first character in STRING.
198A multibyte character is handled correctly. */) 198A multibyte character is handled correctly.
199The value returned is a Unicode codepoint if it is below #x110000 (in
200hex). Codepoints beyond that are Emacs extensions of Unicode. In
201particular, eight-bit characters are returned as codepoints in the
202range #x3FFF80 through #x3FFFFF, inclusive. */)
199 (register Lisp_Object string) 203 (register Lisp_Object string)
200{ 204{
201 register Lisp_Object val; 205 register Lisp_Object val;
@@ -1700,7 +1704,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1700 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1704 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1701{ 1705{
1702 time_t value; 1706 time_t value;
1703 int size; 1707 ptrdiff_t size;
1704 int usec; 1708 int usec;
1705 int ns; 1709 int ns;
1706 struct tm *tm; 1710 struct tm *tm;
@@ -1717,7 +1721,9 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1717 Vlocale_coding_system, 1); 1721 Vlocale_coding_system, 1);
1718 1722
1719 /* This is probably enough. */ 1723 /* This is probably enough. */
1720 size = SBYTES (format_string) * 6 + 50; 1724 size = SBYTES (format_string);
1725 if (size <= (STRING_BYTES_BOUND - 50) / 6)
1726 size = size * 6 + 50;
1721 1727
1722 BLOCK_INPUT; 1728 BLOCK_INPUT;
1723 tm = ut ? gmtime (&value) : localtime (&value); 1729 tm = ut ? gmtime (&value) : localtime (&value);
@@ -1730,7 +1736,7 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1730 while (1) 1736 while (1)
1731 { 1737 {
1732 char *buf = (char *) alloca (size + 1); 1738 char *buf = (char *) alloca (size + 1);
1733 int result; 1739 size_t result;
1734 1740
1735 buf[0] = '\1'; 1741 buf[0] = '\1';
1736 BLOCK_INPUT; 1742 BLOCK_INPUT;
@@ -1749,6 +1755,8 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". */)
1749 SBYTES (format_string), 1755 SBYTES (format_string),
1750 tm, ut, ns); 1756 tm, ut, ns);
1751 UNBLOCK_INPUT; 1757 UNBLOCK_INPUT;
1758 if (STRING_BYTES_BOUND <= result)
1759 string_overflow ();
1752 size = result + 1; 1760 size = result + 1;
1753 } 1761 }
1754} 1762}
@@ -3152,10 +3160,9 @@ It returns the number of characters changed. */)
3152} 3160}
3153 3161
3154DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r", 3162DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r",
3155 doc: /* Delete the text between point and mark. 3163 doc: /* Delete the text between START and END.
3156 3164If called interactively, delete the region between point and mark.
3157When called from a program, expects two arguments, 3165This command deletes buffer text without modifying the kill ring. */)
3158positions (integers or markers) specifying the stretch to be deleted. */)
3159 (Lisp_Object start, Lisp_Object end) 3166 (Lisp_Object start, Lisp_Object end)
3160{ 3167{
3161 validate_region (&start, &end); 3168 validate_region (&start, &end);
@@ -3557,7 +3564,8 @@ The width specifier supplies a lower limit for the length of the
3557printed representation. The padding, if any, normally goes on the 3564printed representation. The padding, if any, normally goes on the
3558left, but it goes on the right if the - flag is present. The padding 3565left, but it goes on the right if the - flag is present. The padding
3559character is normally a space, but it is 0 if the 0 flag is present. 3566character is normally a space, but it is 0 if the 0 flag is present.
3560The - flag takes precedence over the 0 flag. 3567The 0 flag is ignored if the - flag is present, or the format sequence
3568is something other than %d, %e, %f, and %g.
3561 3569
3562For %e, %f, and %g sequences, the number after the "." in the 3570For %e, %f, and %g sequences, the number after the "." in the
3563precision specifier says how many decimal places to show; if zero, the 3571precision specifier says how many decimal places to show; if zero, the
diff --git a/src/emacs.c b/src/emacs.c
index bfefa2bfa51..1de10c0b5dc 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -131,6 +131,10 @@ Lisp_Object empty_unibyte_string, empty_multibyte_string;
131 on subsequent starts. */ 131 on subsequent starts. */
132int initialized; 132int initialized;
133 133
134#ifdef DARWIN_OS
135extern void unexec_init_emacs_zone (void);
136#endif
137
134#ifdef DOUG_LEA_MALLOC 138#ifdef DOUG_LEA_MALLOC
135/* Preserves a pointer to the memory allocated that copies that 139/* Preserves a pointer to the memory allocated that copies that
136 static data inside glibc's malloc. */ 140 static data inside glibc's malloc. */
@@ -352,8 +356,7 @@ fatal_error_signal (int sig)
352 356
353/* Handler for SIGDANGER. */ 357/* Handler for SIGDANGER. */
354void 358void
355memory_warning_signal (sig) 359memory_warning_signal (int sig)
356 int sig;
357{ 360{
358 signal (sig, memory_warning_signal); 361 signal (sig, memory_warning_signal);
359 SIGNAL_THREAD_CHECK (sig); 362 SIGNAL_THREAD_CHECK (sig);
diff --git a/src/eval.c b/src/eval.c
index 6ca8eacb100..90d0df61858 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -32,25 +32,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "xterm.h" 32#include "xterm.h"
33#endif 33#endif
34 34
35/* This definition is duplicated in alloc.c and keyboard.c. */
36/* Putting it in lisp.h makes cc bomb out! */
37
38struct backtrace 35struct backtrace
39{ 36{
40 struct backtrace *next; 37 struct backtrace *next;
41 Lisp_Object *function; 38 Lisp_Object *function;
42 Lisp_Object *args; /* Points to vector of args. */ 39 Lisp_Object *args; /* Points to vector of args. */
43#define NARGS_BITS (BITS_PER_INT - 2) 40 ptrdiff_t nargs; /* Length of vector. */
44 /* Let's not use size_t because we want to allow negative values (for
45 UNEVALLED). Also let's steal 2 bits so we save a word (or more for
46 alignment). In any case I doubt Emacs would survive a function call with
47 more than 500M arguments. */
48 int nargs : NARGS_BITS; /* Length of vector.
49 If nargs is UNEVALLED, args points
50 to slot holding list of unevalled args. */
51 char evalargs : 1;
52 /* Nonzero means call value of debugger when done with this operation. */ 41 /* Nonzero means call value of debugger when done with this operation. */
53 char debug_on_exit : 1; 42 unsigned int debug_on_exit : 1;
54}; 43};
55 44
56static struct backtrace *backtrace_list; 45static struct backtrace *backtrace_list;
@@ -1651,8 +1640,7 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1651} 1640}
1652 1641
1653 1642
1654static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object, 1643static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object);
1655 Lisp_Object, Lisp_Object);
1656static int maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, 1644static int maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig,
1657 Lisp_Object data); 1645 Lisp_Object data);
1658 1646
@@ -1728,8 +1716,7 @@ See also the function `condition-case'. */)
1728 1716
1729 for (h = handlerlist; h; h = h->next) 1717 for (h = handlerlist; h; h = h->next)
1730 { 1718 {
1731 clause = find_handler_clause (h->handler, conditions, 1719 clause = find_handler_clause (h->handler, conditions);
1732 error_symbol, data);
1733 if (!NILP (clause)) 1720 if (!NILP (clause))
1734 break; 1721 break;
1735 } 1722 }
@@ -1900,8 +1887,10 @@ skip_debugger (Lisp_Object conditions, Lisp_Object data)
1900} 1887}
1901 1888
1902/* Call the debugger if calling it is currently enabled for CONDITIONS. 1889/* Call the debugger if calling it is currently enabled for CONDITIONS.
1903 SIG and DATA describe the signal, as in find_handler_clause. */ 1890 SIG and DATA describe the signal. There are two ways to pass them:
1904 1891 = SIG is the error symbol, and DATA is the rest of the data.
1892 = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA).
1893 This is for memory-full errors only. */
1905static int 1894static int
1906maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) 1895maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data)
1907{ 1896{
@@ -1928,19 +1917,8 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data)
1928 return 0; 1917 return 0;
1929} 1918}
1930 1919
1931/* Value of Qlambda means we have called debugger and user has continued.
1932 There are two ways to pass SIG and DATA:
1933 = SIG is the error symbol, and DATA is the rest of the data.
1934 = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA).
1935 This is for memory-full errors only.
1936
1937 We need to increase max_specpdl_size temporarily around
1938 anything we do that can push on the specpdl, so as not to get
1939 a second error here in case we're handling specpdl overflow. */
1940
1941static Lisp_Object 1920static Lisp_Object
1942find_handler_clause (Lisp_Object handlers, Lisp_Object conditions, 1921find_handler_clause (Lisp_Object handlers, Lisp_Object conditions)
1943 Lisp_Object sig, Lisp_Object data)
1944{ 1922{
1945 register Lisp_Object h; 1923 register Lisp_Object h;
1946 1924
@@ -2291,7 +2269,6 @@ eval_sub (Lisp_Object form)
2291 backtrace.function = &original_fun; /* This also protects them from gc. */ 2269 backtrace.function = &original_fun; /* This also protects them from gc. */
2292 backtrace.args = &original_args; 2270 backtrace.args = &original_args;
2293 backtrace.nargs = UNEVALLED; 2271 backtrace.nargs = UNEVALLED;
2294 backtrace.evalargs = 1;
2295 backtrace.debug_on_exit = 0; 2272 backtrace.debug_on_exit = 0;
2296 2273
2297 if (debug_on_next_call) 2274 if (debug_on_next_call)
@@ -2325,10 +2302,7 @@ eval_sub (Lisp_Object form)
2325 xsignal2 (Qwrong_number_of_arguments, original_fun, numargs); 2302 xsignal2 (Qwrong_number_of_arguments, original_fun, numargs);
2326 2303
2327 else if (XSUBR (fun)->max_args == UNEVALLED) 2304 else if (XSUBR (fun)->max_args == UNEVALLED)
2328 { 2305 val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
2329 backtrace.evalargs = 0;
2330 val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
2331 }
2332 else if (XSUBR (fun)->max_args == MANY) 2306 else if (XSUBR (fun)->max_args == MANY)
2333 { 2307 {
2334 /* Pass a vector of evaluated arguments. */ 2308 /* Pass a vector of evaluated arguments. */
@@ -2984,7 +2958,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2984 backtrace.function = &args[0]; 2958 backtrace.function = &args[0];
2985 backtrace.args = &args[1]; 2959 backtrace.args = &args[1];
2986 backtrace.nargs = nargs - 1; 2960 backtrace.nargs = nargs - 1;
2987 backtrace.evalargs = 0;
2988 backtrace.debug_on_exit = 0; 2961 backtrace.debug_on_exit = 0;
2989 2962
2990 if (debug_on_next_call) 2963 if (debug_on_next_call)
@@ -3141,7 +3114,6 @@ apply_lambda (Lisp_Object fun, Lisp_Object args)
3141 3114
3142 backtrace_list->args = arg_vector; 3115 backtrace_list->args = arg_vector;
3143 backtrace_list->nargs = i; 3116 backtrace_list->nargs = i;
3144 backtrace_list->evalargs = 0;
3145 tem = funcall_lambda (fun, numargs, arg_vector); 3117 tem = funcall_lambda (fun, numargs, arg_vector);
3146 3118
3147 /* Do the debug-on-exit now, while arg_vector still exists. */ 3119 /* Do the debug-on-exit now, while arg_vector still exists. */
@@ -3190,7 +3162,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
3190 shouldn't bind any arguments, instead just call the byte-code 3162 shouldn't bind any arguments, instead just call the byte-code
3191 interpreter directly; it will push arguments as necessary. 3163 interpreter directly; it will push arguments as necessary.
3192 3164
3193 Byte-code objects with either a non-existant, or a nil value for 3165 Byte-code objects with either a non-existent, or a nil value for
3194 the `push args' slot (the default), have dynamically-bound 3166 the `push args' slot (the default), have dynamically-bound
3195 arguments, and use the argument-binding code below instead (as do 3167 arguments, and use the argument-binding code below instead (as do
3196 all interpreted functions, even lexically bound ones). */ 3168 all interpreted functions, even lexically bound ones). */
diff --git a/src/fileio.c b/src/fileio.c
index 27fef42960a..c6f8dfe4683 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1755,6 +1755,10 @@ barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
1755 regardless of what access permissions it has. */ 1755 regardless of what access permissions it has. */
1756 if (lstat (SSDATA (encoded_filename), &statbuf) >= 0) 1756 if (lstat (SSDATA (encoded_filename), &statbuf) >= 0)
1757 { 1757 {
1758 if (S_ISDIR (statbuf.st_mode))
1759 xsignal2 (Qfile_error,
1760 build_string ("File is a directory"), absname);
1761
1758 if (! interactive) 1762 if (! interactive)
1759 xsignal2 (Qfile_already_exists, 1763 xsignal2 (Qfile_already_exists,
1760 build_string ("File already exists"), absname); 1764 build_string ("File already exists"), absname);
diff --git a/src/floatfns.c b/src/floatfns.c
index b5c8b4af5c3..e003f492fe6 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -961,8 +961,7 @@ Rounds the value toward zero. */)
961 961
962#ifdef FLOAT_CATCH_SIGILL 962#ifdef FLOAT_CATCH_SIGILL
963static void 963static void
964float_error (signo) 964float_error (int signo)
965 int signo;
966{ 965{
967 if (! in_float) 966 if (! in_float)
968 fatal_error_signal (signo); 967 fatal_error_signal (signo);
diff --git a/src/fns.c b/src/fns.c
index b6fe2a7f7b6..0ca731ed331 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -79,10 +79,14 @@ Other values of LIMIT are ignored. */)
79{ 79{
80 EMACS_INT val; 80 EMACS_INT val;
81 Lisp_Object lispy_val; 81 Lisp_Object lispy_val;
82 EMACS_UINT denominator;
83 82
84 if (EQ (limit, Qt)) 83 if (EQ (limit, Qt))
85 seed_random (getpid () + time (NULL)); 84 {
85 EMACS_TIME t;
86 EMACS_GET_TIME (t);
87 seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_USECS (t));
88 }
89
86 if (NATNUMP (limit) && XFASTINT (limit) != 0) 90 if (NATNUMP (limit) && XFASTINT (limit) != 0)
87 { 91 {
88 /* Try to take our random number from the higher bits of VAL, 92 /* Try to take our random number from the higher bits of VAL,
@@ -92,7 +96,7 @@ Other values of LIMIT are ignored. */)
92 it's possible to get a quotient larger than n; discarding 96 it's possible to get a quotient larger than n; discarding
93 these values eliminates the bias that would otherwise appear 97 these values eliminates the bias that would otherwise appear
94 when using a large n. */ 98 when using a large n. */
95 denominator = ((EMACS_UINT) 1 << VALBITS) / XFASTINT (limit); 99 EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit);
96 do 100 do
97 val = get_random () / denominator; 101 val = get_random () / denominator;
98 while (val >= XFASTINT (limit)); 102 while (val >= XFASTINT (limit));
@@ -2613,6 +2617,7 @@ is not loaded; so load the file FILENAME.
2613If FILENAME is omitted, the printname of FEATURE is used as the file name, 2617If FILENAME is omitted, the printname of FEATURE is used as the file name,
2614and `load' will try to load this name appended with the suffix `.elc' or 2618and `load' will try to load this name appended with the suffix `.elc' or
2615`.el', in that order. The name without appended suffix will not be used. 2619`.el', in that order. The name without appended suffix will not be used.
2620See `get-load-suffixes' for the complete list of suffixes.
2616If the optional third argument NOERROR is non-nil, 2621If the optional third argument NOERROR is non-nil,
2617then return nil if the file is not found instead of signaling an error. 2622then return nil if the file is not found instead of signaling an error.
2618Normally the return value is FEATURE. 2623Normally the return value is FEATURE.
diff --git a/src/font.c b/src/font.c
index 14390335f3c..5f8d22157d6 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1738,8 +1738,7 @@ font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Objec
1738#define LGSTRING_GLYPH_SIZE 8 1738#define LGSTRING_GLYPH_SIZE 8
1739 1739
1740static int 1740static int
1741check_gstring (gstring) 1741check_gstring (Lisp_Object gstring)
1742 Lisp_Object gstring;
1743{ 1742{
1744 Lisp_Object val; 1743 Lisp_Object val;
1745 int i, j; 1744 int i, j;
@@ -1793,8 +1792,7 @@ check_gstring (gstring)
1793} 1792}
1794 1793
1795static void 1794static void
1796check_otf_features (otf_features) 1795check_otf_features (Lisp_Object otf_features)
1797 Lisp_Object otf_features;
1798{ 1796{
1799 Lisp_Object val; 1797 Lisp_Object val;
1800 1798
@@ -1827,8 +1825,7 @@ check_otf_features (otf_features)
1827Lisp_Object otf_list; 1825Lisp_Object otf_list;
1828 1826
1829static Lisp_Object 1827static Lisp_Object
1830otf_tag_symbol (tag) 1828otf_tag_symbol (OTF_Tag tag)
1831 OTF_Tag tag;
1832{ 1829{
1833 char name[5]; 1830 char name[5];
1834 1831
@@ -1837,8 +1834,7 @@ otf_tag_symbol (tag)
1837} 1834}
1838 1835
1839static OTF * 1836static OTF *
1840otf_open (file) 1837otf_open (Lisp_Object file)
1841 Lisp_Object file;
1842{ 1838{
1843 Lisp_Object val = Fassoc (file, otf_list); 1839 Lisp_Object val = Fassoc (file, otf_list);
1844 OTF *otf; 1840 OTF *otf;
@@ -1860,8 +1856,7 @@ otf_open (file)
1860 (struct font_driver).otf_capability. */ 1856 (struct font_driver).otf_capability. */
1861 1857
1862Lisp_Object 1858Lisp_Object
1863font_otf_capability (font) 1859font_otf_capability (struct font *font)
1864 struct font *font;
1865{ 1860{
1866 OTF *otf; 1861 OTF *otf;
1867 Lisp_Object capability = Fcons (Qnil, Qnil); 1862 Lisp_Object capability = Fcons (Qnil, Qnil);
@@ -1935,9 +1930,7 @@ font_otf_capability (font)
1935 FEATURES. */ 1930 FEATURES. */
1936 1931
1937static void 1932static void
1938generate_otf_features (spec, features) 1933generate_otf_features (Lisp_Object spec, char *features)
1939 Lisp_Object spec;
1940 char *features;
1941{ 1934{
1942 Lisp_Object val; 1935 Lisp_Object val;
1943 char *p; 1936 char *p;
@@ -1972,8 +1965,7 @@ generate_otf_features (spec, features)
1972} 1965}
1973 1966
1974Lisp_Object 1967Lisp_Object
1975font_otf_DeviceTable (device_table) 1968font_otf_DeviceTable (OTF_DeviceTable *device_table)
1976 OTF_DeviceTable *device_table;
1977{ 1969{
1978 int len = device_table->StartSize - device_table->EndSize + 1; 1970 int len = device_table->StartSize - device_table->EndSize + 1;
1979 1971
@@ -1982,9 +1974,7 @@ font_otf_DeviceTable (device_table)
1982} 1974}
1983 1975
1984Lisp_Object 1976Lisp_Object
1985font_otf_ValueRecord (value_format, value_record) 1977font_otf_ValueRecord (int value_format, OTF_ValueRecord *value_record)
1986 int value_format;
1987 OTF_ValueRecord *value_record;
1988{ 1978{
1989 Lisp_Object val = Fmake_vector (make_number (8), Qnil); 1979 Lisp_Object val = Fmake_vector (make_number (8), Qnil);
1990 1980
@@ -2008,8 +1998,7 @@ font_otf_ValueRecord (value_format, value_record)
2008} 1998}
2009 1999
2010Lisp_Object 2000Lisp_Object
2011font_otf_Anchor (anchor) 2001font_otf_Anchor (OTF_Anchor *anchor)
2012 OTF_Anchor *anchor;
2013{ 2002{
2014 Lisp_Object val; 2003 Lisp_Object val;
2015 2004
@@ -3739,8 +3728,9 @@ font_range (EMACS_INT pos, EMACS_INT *limit, struct window *w, struct face *face
3739 else 3728 else
3740 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte); 3729 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte);
3741 category = CHAR_TABLE_REF (Vunicode_category_table, c); 3730 category = CHAR_TABLE_REF (Vunicode_category_table, c);
3742 if (EQ (category, QCf) 3731 if (INTEGERP (category)
3743 || CHAR_VARIATION_SELECTOR_P (c)) 3732 && (XINT (category) == UNICODE_CATEGORY_Cf
3733 || CHAR_VARIATION_SELECTOR_P (c)))
3744 continue; 3734 continue;
3745 if (NILP (font_object)) 3735 if (NILP (font_object))
3746 { 3736 {
diff --git a/src/gnutls.c b/src/gnutls.c
index 2a055ac40f0..3761951b866 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -143,10 +143,12 @@ static int
143init_gnutls_functions (Lisp_Object libraries) 143init_gnutls_functions (Lisp_Object libraries)
144{ 144{
145 HMODULE library; 145 HMODULE library;
146 Lisp_Object gnutls_log_level = Fsymbol_value (Qgnutls_log_level);
147 int max_log_level = 1;
146 148
147 if (!(library = w32_delayed_load (libraries, Qgnutls_dll))) 149 if (!(library = w32_delayed_load (libraries, Qgnutls_dll)))
148 { 150 {
149 GNUTLS_LOG (1, 1, "GnuTLS library not found"); 151 GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
150 return 0; 152 return 0;
151 } 153 }
152 154
@@ -189,7 +191,10 @@ init_gnutls_functions (Lisp_Object libraries)
189 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import); 191 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
190 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init); 192 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
191 193
192 GNUTLS_LOG2 (1, 1, "GnuTLS library loaded:", 194 if (NUMBERP (gnutls_log_level))
195 max_log_level = XINT (gnutls_log_level);
196
197 GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
193 SDATA (Fget (Qgnutls_dll, QCloaded_from))); 198 SDATA (Fget (Qgnutls_dll, QCloaded_from)));
194 return 1; 199 return 1;
195} 200}
@@ -379,7 +384,7 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte)
379 /* non-fatal error */ 384 /* non-fatal error */
380 return -1; 385 return -1;
381 else { 386 else {
382 /* a fatal error occured */ 387 /* a fatal error occurred */
383 return 0; 388 return 0;
384 } 389 }
385} 390}
@@ -638,9 +643,6 @@ certificates for `gnutls-x509pki'.
638:verify-flags is a bitset as per GnuTLS' 643:verify-flags is a bitset as per GnuTLS'
639gnutls_certificate_set_verify_flags. 644gnutls_certificate_set_verify_flags.
640 645
641:verify-error, if non-nil, makes failure of the certificate validation
642an error. Otherwise it will be just a series of warnings.
643
644:verify-hostname-error, if non-nil, makes a hostname mismatch an 646:verify-hostname-error, if non-nil, makes a hostname mismatch an
645error. Otherwise it will be just a warning. 647error. Otherwise it will be just a warning.
646 648
@@ -1100,36 +1102,35 @@ syms_of_gnutls (void)
1100{ 1102{
1101 gnutls_global_initialized = 0; 1103 gnutls_global_initialized = 0;
1102 1104
1103 DEFSYM(Qgnutls_dll, "gnutls"); 1105 DEFSYM (Qgnutls_dll, "gnutls");
1104 DEFSYM(Qgnutls_log_level, "gnutls-log-level"); 1106 DEFSYM (Qgnutls_log_level, "gnutls-log-level");
1105 DEFSYM(Qgnutls_code, "gnutls-code"); 1107 DEFSYM (Qgnutls_code, "gnutls-code");
1106 DEFSYM(Qgnutls_anon, "gnutls-anon"); 1108 DEFSYM (Qgnutls_anon, "gnutls-anon");
1107 DEFSYM(Qgnutls_x509pki, "gnutls-x509pki"); 1109 DEFSYM (Qgnutls_x509pki, "gnutls-x509pki");
1108 DEFSYM(Qgnutls_bootprop_hostname, ":hostname"); 1110 DEFSYM (Qgnutls_bootprop_hostname, ":hostname");
1109 DEFSYM(Qgnutls_bootprop_priority, ":priority"); 1111 DEFSYM (Qgnutls_bootprop_priority, ":priority");
1110 DEFSYM(Qgnutls_bootprop_trustfiles, ":trustfiles"); 1112 DEFSYM (Qgnutls_bootprop_trustfiles, ":trustfiles");
1111 DEFSYM(Qgnutls_bootprop_keylist, ":keylist"); 1113 DEFSYM (Qgnutls_bootprop_keylist, ":keylist");
1112 DEFSYM(Qgnutls_bootprop_crlfiles, ":crlfiles"); 1114 DEFSYM (Qgnutls_bootprop_crlfiles, ":crlfiles");
1113 DEFSYM(Qgnutls_bootprop_callbacks, ":callbacks"); 1115 DEFSYM (Qgnutls_bootprop_callbacks, ":callbacks");
1114 DEFSYM(Qgnutls_bootprop_callbacks_verify, "verify"); 1116 DEFSYM (Qgnutls_bootprop_callbacks_verify, "verify");
1115 DEFSYM(Qgnutls_bootprop_loglevel, ":loglevel"); 1117 DEFSYM (Qgnutls_bootprop_loglevel, ":loglevel");
1116 DEFSYM(Qgnutls_bootprop_verify_flags, ":verify-flags"); 1118 DEFSYM (Qgnutls_bootprop_verify_flags, ":verify-flags");
1117 DEFSYM(Qgnutls_bootprop_verify_hostname_error, ":verify-error"); 1119 DEFSYM (Qgnutls_bootprop_verify_hostname_error, ":verify-hostname-error");
1118 DEFSYM(Qgnutls_bootprop_verify_hostname_error, ":verify-hostname-error"); 1120
1119 1121 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
1120 DEFSYM(Qgnutls_e_interrupted, "gnutls-e-interrupted");
1121 Fput (Qgnutls_e_interrupted, Qgnutls_code, 1122 Fput (Qgnutls_e_interrupted, Qgnutls_code,
1122 make_number (GNUTLS_E_INTERRUPTED)); 1123 make_number (GNUTLS_E_INTERRUPTED));
1123 1124
1124 DEFSYM(Qgnutls_e_again, "gnutls-e-again"); 1125 DEFSYM (Qgnutls_e_again, "gnutls-e-again");
1125 Fput (Qgnutls_e_again, Qgnutls_code, 1126 Fput (Qgnutls_e_again, Qgnutls_code,
1126 make_number (GNUTLS_E_AGAIN)); 1127 make_number (GNUTLS_E_AGAIN));
1127 1128
1128 DEFSYM(Qgnutls_e_invalid_session, "gnutls-e-invalid-session"); 1129 DEFSYM (Qgnutls_e_invalid_session, "gnutls-e-invalid-session");
1129 Fput (Qgnutls_e_invalid_session, Qgnutls_code, 1130 Fput (Qgnutls_e_invalid_session, Qgnutls_code,
1130 make_number (GNUTLS_E_INVALID_SESSION)); 1131 make_number (GNUTLS_E_INVALID_SESSION));
1131 1132
1132 DEFSYM(Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake"); 1133 DEFSYM (Qgnutls_e_not_ready_for_handshake, "gnutls-e-not-ready-for-handshake");
1133 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code, 1134 Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code,
1134 make_number (GNUTLS_E_APPLICATION_ERROR_MIN)); 1135 make_number (GNUTLS_E_APPLICATION_ERROR_MIN));
1135 1136
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 48571bef275..1a16246f2b8 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -633,6 +633,9 @@ qttip_cb (GtkWidget *widget,
633 struct x_output *x = f->output_data.x; 633 struct x_output *x = f->output_data.x;
634 if (x->ttip_widget == NULL) 634 if (x->ttip_widget == NULL)
635 { 635 {
636 GtkWidget *p;
637 GList *list, *iter;
638
636 g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL); 639 g_object_set (G_OBJECT (widget), "has-tooltip", FALSE, NULL);
637 x->ttip_widget = tooltip; 640 x->ttip_widget = tooltip;
638 g_object_ref (G_OBJECT (tooltip)); 641 g_object_ref (G_OBJECT (tooltip));
@@ -640,6 +643,18 @@ qttip_cb (GtkWidget *widget,
640 g_object_ref (G_OBJECT (x->ttip_lbl)); 643 g_object_ref (G_OBJECT (x->ttip_lbl));
641 gtk_tooltip_set_custom (tooltip, x->ttip_lbl); 644 gtk_tooltip_set_custom (tooltip, x->ttip_lbl);
642 x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl)); 645 x->ttip_window = GTK_WINDOW (gtk_widget_get_toplevel (x->ttip_lbl));
646
647 /* Change stupid Gtk+ default line wrapping. */
648 p = gtk_widget_get_parent (x->ttip_lbl);
649 list = gtk_container_get_children (GTK_CONTAINER (p));
650 for (iter = list; iter; iter = g_list_next (iter))
651 {
652 GtkWidget *w = GTK_WIDGET (iter->data);
653 if (GTK_IS_LABEL (w))
654 gtk_label_set_line_wrap (GTK_LABEL (w), FALSE);
655 }
656 g_list_free (list);
657
643 /* ATK needs an empty title for some reason. */ 658 /* ATK needs an empty title for some reason. */
644 gtk_window_set_title (x->ttip_window, ""); 659 gtk_window_set_title (x->ttip_window, "");
645 /* Realize so we can safely get screen later on. */ 660 /* Realize so we can safely get screen later on. */
@@ -659,8 +674,8 @@ qttip_cb (GtkWidget *widget,
659 674
660int 675int
661xg_prepare_tooltip (FRAME_PTR f, 676xg_prepare_tooltip (FRAME_PTR f,
662 Lisp_Object string, 677 Lisp_Object string,
663 int *width, 678 int *width,
664 int *height) 679 int *height)
665{ 680{
666#ifndef USE_GTK_TOOLTIP 681#ifndef USE_GTK_TOOLTIP
@@ -697,10 +712,9 @@ xg_prepare_tooltip (FRAME_PTR f,
697 (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))), 712 (gtk_widget_get_display (GTK_WIDGET (x->ttip_window))),
698 "gdk-display-current-tooltip", NULL); 713 "gdk-display-current-tooltip", NULL);
699 714
700 /* Put out dummy widget in so we can get callbacks for unrealize and 715 /* Put our dummy widget in so we can get callbacks for unrealize and
701 hierarchy-changed. */ 716 hierarchy-changed. */
702 gtk_tooltip_set_custom (x->ttip_widget, widget); 717 gtk_tooltip_set_custom (x->ttip_widget, widget);
703
704 gtk_tooltip_set_text (x->ttip_widget, SSDATA (encoded_string)); 718 gtk_tooltip_set_text (x->ttip_widget, SSDATA (encoded_string));
705 gtk_widget_get_preferred_size (GTK_WIDGET (x->ttip_window), NULL, &req); 719 gtk_widget_get_preferred_size (GTK_WIDGET (x->ttip_window), NULL, &req);
706 if (width) *width = req.width; 720 if (width) *width = req.width;
@@ -731,7 +745,7 @@ xg_show_tooltip (FRAME_PTR f, int root_x, int root_y)
731} 745}
732 746
733/* Hide tooltip if shown. Do nothing if not shown. 747/* Hide tooltip if shown. Do nothing if not shown.
734 Return non-zero if tip was hidden, non-ero if not (i.e. not using 748 Return non-zero if tip was hidden, non-zero if not (i.e. not using
735 system tooltips). */ 749 system tooltips). */
736 750
737int 751int
diff --git a/src/image.c b/src/image.c
index 6e8440fb431..fa39ff12681 100644
--- a/src/image.c
+++ b/src/image.c
@@ -5007,9 +5007,7 @@ pbm_scan_number (unsigned char **s, unsigned char *end)
5007 occurred. *SIZE is set to the size of the file. */ 5007 occurred. *SIZE is set to the size of the file. */
5008 5008
5009static char * 5009static char *
5010pbm_read_file (file, size) 5010pbm_read_file (Lisp_Object file, int *size)
5011 Lisp_Object file;
5012 int *size;
5013{ 5011{
5014 FILE *fp = NULL; 5012 FILE *fp = NULL;
5015 char *buf = NULL; 5013 char *buf = NULL;
diff --git a/src/indent.c b/src/indent.c
index 02d99d14ded..aaeaaf591ef 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -725,8 +725,7 @@ current_column_1 (void)
725 If END is nil, that stands for the end of STRING. */ 725 If END is nil, that stands for the end of STRING. */
726 726
727static double 727static double
728string_display_width (string, beg, end) 728string_display_width (Lisp_Object string, Lisp_Object beg, Lisp_Object end)
729 Lisp_Object string, beg, end;
730{ 729{
731 register int col; 730 register int col;
732 register unsigned char *ptr, *stop; 731 register unsigned char *ptr, *stop;
@@ -1986,9 +1985,11 @@ whether or not it is currently displayed in some window. */)
1986 struct text_pos pt; 1985 struct text_pos pt;
1987 struct window *w; 1986 struct window *w;
1988 Lisp_Object old_buffer; 1987 Lisp_Object old_buffer;
1989 struct gcpro gcpro1; 1988 EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0);
1989 struct gcpro gcpro1, gcpro2, gcpro3;
1990 Lisp_Object lcols = Qnil; 1990 Lisp_Object lcols = Qnil;
1991 double cols IF_LINT (= 0); 1991 double cols IF_LINT (= 0);
1992 void *itdata = NULL;
1992 1993
1993 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ 1994 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
1994 if (CONSP (lines) && (NUMBERP (XCAR (lines)))) 1995 if (CONSP (lines) && (NUMBERP (XCAR (lines))))
@@ -2006,12 +2007,16 @@ whether or not it is currently displayed in some window. */)
2006 w = XWINDOW (window); 2007 w = XWINDOW (window);
2007 2008
2008 old_buffer = Qnil; 2009 old_buffer = Qnil;
2009 GCPRO1 (old_buffer); 2010 GCPRO3 (old_buffer, old_charpos, old_bytepos);
2010 if (XBUFFER (w->buffer) != current_buffer) 2011 if (XBUFFER (w->buffer) != current_buffer)
2011 { 2012 {
2012 /* Set the window's buffer temporarily to the current buffer. */ 2013 /* Set the window's buffer temporarily to the current buffer. */
2013 old_buffer = w->buffer; 2014 old_buffer = w->buffer;
2015 old_charpos = XMARKER (w->pointm)->charpos;
2016 old_bytepos = XMARKER (w->pointm)->bytepos;
2014 XSETBUFFER (w->buffer, current_buffer); 2017 XSETBUFFER (w->buffer, current_buffer);
2018 set_marker_both
2019 (w->pointm, w->buffer, BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
2015 } 2020 }
2016 2021
2017 if (noninteractive) 2022 if (noninteractive)
@@ -2025,6 +2030,7 @@ whether or not it is currently displayed in some window. */)
2025 EMACS_INT it_start; 2030 EMACS_INT it_start;
2026 int first_x, it_overshoot_expected IF_LINT (= 0); 2031 int first_x, it_overshoot_expected IF_LINT (= 0);
2027 2032
2033 itdata = bidi_shelve_cache ();
2028 SET_TEXT_POS (pt, PT, PT_BYTE); 2034 SET_TEXT_POS (pt, PT, PT_BYTE);
2029 start_display (&it, w, pt); 2035 start_display (&it, w, pt);
2030 first_x = it.first_visible_x; 2036 first_x = it.first_visible_x;
@@ -2129,10 +2135,14 @@ whether or not it is currently displayed in some window. */)
2129 } 2135 }
2130 2136
2131 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 2137 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2138 bidi_unshelve_cache (itdata);
2132 } 2139 }
2133 2140
2134 if (BUFFERP (old_buffer)) 2141 if (BUFFERP (old_buffer))
2135 w->buffer = old_buffer; 2142 {
2143 w->buffer = old_buffer;
2144 set_marker_both (w->pointm, w->buffer, old_charpos, old_bytepos);
2145 }
2136 2146
2137 RETURN_UNGCPRO (make_number (it.vpos)); 2147 RETURN_UNGCPRO (make_number (it.vpos));
2138} 2148}
diff --git a/src/intervals.c b/src/intervals.c
index 4de001f2ffc..2063655cdb9 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -247,8 +247,7 @@ static int zero_length;
247INTERVAL search_interval, found_interval; 247INTERVAL search_interval, found_interval;
248 248
249void 249void
250check_for_interval (i) 250check_for_interval (INTERVAL i)
251 register INTERVAL i;
252{ 251{
253 if (i == search_interval) 252 if (i == search_interval)
254 { 253 {
@@ -258,8 +257,7 @@ check_for_interval (i)
258} 257}
259 258
260INTERVAL 259INTERVAL
261search_for_interval (i, tree) 260search_for_interval (INTERVAL i, INTERVAL tree)
262 register INTERVAL i, tree;
263{ 261{
264 icount = 0; 262 icount = 0;
265 search_interval = i; 263 search_interval = i;
@@ -269,8 +267,7 @@ search_for_interval (i, tree)
269} 267}
270 268
271static void 269static void
272inc_interval_count (i) 270inc_interval_count (INTERVAL i)
273 INTERVAL i;
274{ 271{
275 icount++; 272 icount++;
276 if (LENGTH (i) == 0) 273 if (LENGTH (i) == 0)
@@ -280,8 +277,7 @@ inc_interval_count (i)
280} 277}
281 278
282int 279int
283count_intervals (i) 280count_intervals (INTERVAL i)
284 register INTERVAL i;
285{ 281{
286 icount = 0; 282 icount = 0;
287 idepth = 0; 283 idepth = 0;
@@ -292,8 +288,7 @@ count_intervals (i)
292} 288}
293 289
294static INTERVAL 290static INTERVAL
295root_interval (interval) 291root_interval (INTERVAL interval)
296 INTERVAL interval;
297{ 292{
298 register INTERVAL i = interval; 293 register INTERVAL i = interval;
299 294
@@ -804,9 +799,8 @@ update_interval (register INTERVAL i, EMACS_INT pos)
804 to the root. */ 799 to the root. */
805 800
806static INTERVAL 801static INTERVAL
807adjust_intervals_for_insertion (tree, position, length) 802adjust_intervals_for_insertion (INTERVAL tree, EMACS_INT position,
808 INTERVAL tree; 803 EMACS_INT length)
809 EMACS_INT position, length;
810{ 804{
811 register EMACS_INT relative_position; 805 register EMACS_INT relative_position;
812 register INTERVAL this; 806 register INTERVAL this;
@@ -1615,9 +1609,7 @@ reproduce_tree_obj (INTERVAL source, Lisp_Object parent)
1615 interval. */ 1609 interval. */
1616 1610
1617static INTERVAL 1611static INTERVAL
1618make_new_interval (intervals, start, length) 1612make_new_interval (INTERVAL intervals, EMACS_INT start, EMACS_INT length)
1619 INTERVAL intervals;
1620 EMACS_INT start, length;
1621{ 1613{
1622 INTERVAL slot; 1614 INTERVAL slot;
1623 1615
diff --git a/src/keyboard.c b/src/keyboard.c
index 2d9643d455c..60c6283dab5 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1540,7 +1540,18 @@ command_loop_1 (void)
1540 message_with_string ("%s is undefined", keys, 0); 1540 message_with_string ("%s is undefined", keys, 0);
1541 KVAR (current_kboard, defining_kbd_macro) = Qnil; 1541 KVAR (current_kboard, defining_kbd_macro) = Qnil;
1542 update_mode_lines = 1; 1542 update_mode_lines = 1;
1543 KVAR (current_kboard, Vprefix_arg) = Qnil; 1543 /* If this is a down-mouse event, don't reset prefix-arg;
1544 pass it to the command run by the up event. */
1545 if (EVENT_HAS_PARAMETERS (last_command_event))
1546 {
1547 Lisp_Object breakdown
1548 = parse_modifiers (EVENT_HEAD (last_command_event));
1549 int modifiers = XINT (XCAR (XCDR (breakdown)));
1550 if (!(modifiers & down_modifier))
1551 KVAR (current_kboard, Vprefix_arg) = Qnil;
1552 }
1553 else
1554 KVAR (current_kboard, Vprefix_arg) = Qnil;
1544 } 1555 }
1545 else 1556 else
1546 { 1557 {
@@ -7478,7 +7489,7 @@ menu_bar_items (Lisp_Object old)
7478 if (CONSP (def)) 7489 if (CONSP (def))
7479 { 7490 {
7480 menu_bar_one_keymap_changed_items = Qnil; 7491 menu_bar_one_keymap_changed_items = Qnil;
7481 map_keymap (def, menu_bar_item, Qnil, NULL, 1); 7492 map_keymap_canonical (def, menu_bar_item, Qnil, NULL);
7482 } 7493 }
7483 } 7494 }
7484 7495
@@ -7819,7 +7830,7 @@ parse_menu_item (Lisp_Object item, int inmenubar)
7819 /* If we got no definition, this item is just unselectable text which 7830 /* If we got no definition, this item is just unselectable text which
7820 is OK in a submenu but not in the menubar. */ 7831 is OK in a submenu but not in the menubar. */
7821 if (NILP (def)) 7832 if (NILP (def))
7822 return (inmenubar ? 0 : 1); 7833 return (!inmenubar);
7823 7834
7824 /* See if this is a separate pane or a submenu. */ 7835 /* See if this is a separate pane or a submenu. */
7825 def = AREF (item_properties, ITEM_PROPERTY_DEF); 7836 def = AREF (item_properties, ITEM_PROPERTY_DEF);
@@ -10640,7 +10651,8 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
10640DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, 10651DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
10641 "FOpen dribble file: ", 10652 "FOpen dribble file: ",
10642 doc: /* Start writing all keyboard characters to a dribble file called FILE. 10653 doc: /* Start writing all keyboard characters to a dribble file called FILE.
10643If FILE is nil, close any open dribble file. */) 10654If FILE is nil, close any open dribble file.
10655The file will be closed when Emacs exits. */)
10644 (Lisp_Object file) 10656 (Lisp_Object file)
10645{ 10657{
10646 if (dribble) 10658 if (dribble)
diff --git a/src/keymap.c b/src/keymap.c
index ac7f651e283..0169276bef9 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -16,6 +16,27 @@ GNU General Public License for more details.
16You should have received a copy of the GNU General Public License 16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19/* Old BUGS:
20 - [M-C-a] != [?\M-\C-a]
21 - [M-f2] != [?\e f2].
22 - (define-key map [menu-bar foo] <bla>) does not always place <bla>
23 at the head of the menu (if `foo' was already bound earlier and
24 then unbound, for example).
25 TODO:
26 - allow many more Meta -> ESC mappings (like Hyper -> C-e for Emacspeak)
27 - Think about the various defaulting that's currently hard-coded in
28 keyboard.c (uppercase->lowercase, char->charset, button-events, ...)
29 and make it more generic. Maybe we should allow mappings of the
30 form (PREDICATE . BINDING) as generalization of the default binding,
31 tho probably a cleaner way to attack this is to allow functional
32 keymaps (i.e. keymaps that are implemented as functions that implement
33 a few different methods like `lookup', `map', ...).
34 - Make [a] equivalent to [?a].
35 BEWARE:
36 - map-keymap should work meaningfully even if entries are added/removed
37 to the keymap while iterating through it:
38 start - removed <= visited <= start + added
39 */
19 40
20#include <config.h> 41#include <config.h>
21#include <stdio.h> 42#include <stdio.h>
@@ -73,7 +94,6 @@ static Lisp_Object where_is_cache_keymaps;
73 94
74static Lisp_Object Flookup_key (Lisp_Object, Lisp_Object, Lisp_Object); 95static Lisp_Object Flookup_key (Lisp_Object, Lisp_Object, Lisp_Object);
75static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object); 96static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object);
76static void fix_submap_inheritance (Lisp_Object, Lisp_Object, Lisp_Object);
77 97
78static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object); 98static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object);
79static void describe_command (Lisp_Object, Lisp_Object); 99static void describe_command (Lisp_Object, Lisp_Object);
@@ -130,6 +150,17 @@ in case you use it as a menu with `x-popup-menu'. */)
130 return Fcons (Qkeymap, Qnil); 150 return Fcons (Qkeymap, Qnil);
131} 151}
132 152
153DEFUN ("make-composed-keymap", Fmake_composed_keymap, Smake_composed_keymap,
154 0, MANY, 0,
155 doc: /* Construct and return a new keymap composed of KEYMAPS.
156When looking up a key in the returned map, the key is looked in each
157keymap in turn until a binding is found.
158usage: (make-composed-keymap &rest KEYMAPS) */)
159 (ptrdiff_t nargs, Lisp_Object *args)
160{
161 return Fcons (Qkeymap, Flist (nargs, args));
162}
163
133/* This function is used for installing the standard key bindings 164/* This function is used for installing the standard key bindings
134 at initialization time. 165 at initialization time.
135 166
@@ -174,6 +205,12 @@ when reading a key-sequence to be looked-up in this keymap. */)
174 Lisp_Object tem = XCAR (map); 205 Lisp_Object tem = XCAR (map);
175 if (STRINGP (tem)) 206 if (STRINGP (tem))
176 return tem; 207 return tem;
208 else if (KEYMAPP (tem))
209 {
210 tem = Fkeymap_prompt (tem);
211 if (!NILP (tem))
212 return tem;
213 }
177 map = XCDR (map); 214 map = XCDR (map);
178 } 215 }
179 return Qnil; 216 return Qnil;
@@ -300,23 +337,16 @@ Return PARENT. PARENT should be nil or another keymap. */)
300{ 337{
301 Lisp_Object list, prev; 338 Lisp_Object list, prev;
302 struct gcpro gcpro1, gcpro2; 339 struct gcpro gcpro1, gcpro2;
303 int i;
304 340
305 /* Force a keymap flush for the next call to where-is. 341 /* Flush any reverse-map cache. */
306 Since this can be called from within where-is, we don't set where_is_cache 342 where_is_cache = Qnil; where_is_cache_keymaps = Qt;
307 directly but only where_is_cache_keymaps, since where_is_cache shouldn't
308 be changed during where-is, while where_is_cache_keymaps is only used at
309 the very beginning of where-is and can thus be changed here without any
310 adverse effect.
311 This is a very minor correctness (rather than safety) issue. */
312 where_is_cache_keymaps = Qt;
313 343
314 GCPRO2 (keymap, parent); 344 GCPRO2 (keymap, parent);
315 keymap = get_keymap (keymap, 1, 1); 345 keymap = get_keymap (keymap, 1, 1);
316 346
317 if (!NILP (parent)) 347 if (!NILP (parent))
318 { 348 {
319 parent = get_keymap (parent, 1, 1); 349 parent = get_keymap (parent, 1, 0);
320 350
321 /* Check for cycles. */ 351 /* Check for cycles. */
322 if (keymap_memberp (keymap, parent)) 352 if (keymap_memberp (keymap, parent))
@@ -332,121 +362,35 @@ Return PARENT. PARENT should be nil or another keymap. */)
332 If we came to the end, add the parent in PREV. */ 362 If we came to the end, add the parent in PREV. */
333 if (!CONSP (list) || KEYMAPP (list)) 363 if (!CONSP (list) || KEYMAPP (list))
334 { 364 {
335 /* If we already have the right parent, return now
336 so that we avoid the loops below. */
337 if (EQ (XCDR (prev), parent))
338 RETURN_UNGCPRO (parent);
339
340 CHECK_IMPURE (prev); 365 CHECK_IMPURE (prev);
341 XSETCDR (prev, parent); 366 XSETCDR (prev, parent);
342 break; 367 RETURN_UNGCPRO (parent);
343 } 368 }
344 prev = list; 369 prev = list;
345 } 370 }
346
347 /* Scan through for submaps, and set their parents too. */
348
349 for (list = XCDR (keymap); CONSP (list); list = XCDR (list))
350 {
351 /* Stop the scan when we come to the parent. */
352 if (EQ (XCAR (list), Qkeymap))
353 break;
354
355 /* If this element holds a prefix map, deal with it. */
356 if (CONSP (XCAR (list))
357 && CONSP (XCDR (XCAR (list))))
358 fix_submap_inheritance (keymap, XCAR (XCAR (list)),
359 XCDR (XCAR (list)));
360
361 if (VECTORP (XCAR (list)))
362 for (i = 0; i < ASIZE (XCAR (list)); i++)
363 if (CONSP (XVECTOR (XCAR (list))->contents[i]))
364 fix_submap_inheritance (keymap, make_number (i),
365 XVECTOR (XCAR (list))->contents[i]);
366
367 if (CHAR_TABLE_P (XCAR (list)))
368 {
369 map_char_table (fix_submap_inheritance, Qnil, XCAR (list), keymap);
370 }
371 }
372
373 RETURN_UNGCPRO (parent);
374}
375
376/* EVENT is defined in MAP as a prefix, and SUBMAP is its definition.
377 if EVENT is also a prefix in MAP's parent,
378 make sure that SUBMAP inherits that definition as its own parent. */
379
380static void
381fix_submap_inheritance (Lisp_Object map, Lisp_Object event, Lisp_Object submap)
382{
383 Lisp_Object map_parent, parent_entry;
384
385 /* SUBMAP is a cons that we found as a key binding.
386 Discard the other things found in a menu key binding. */
387
388 submap = get_keymap (get_keyelt (submap, 0), 0, 0);
389
390 /* If it isn't a keymap now, there's no work to do. */
391 if (!CONSP (submap))
392 return;
393
394 map_parent = keymap_parent (map, 0);
395 if (!NILP (map_parent))
396 parent_entry =
397 get_keymap (access_keymap (map_parent, event, 0, 0, 0), 0, 0);
398 else
399 parent_entry = Qnil;
400
401 /* If MAP's parent has something other than a keymap,
402 our own submap shadows it completely. */
403 if (!CONSP (parent_entry))
404 return;
405
406 if (! EQ (parent_entry, submap))
407 {
408 Lisp_Object submap_parent;
409 submap_parent = submap;
410 while (1)
411 {
412 Lisp_Object tem;
413
414 tem = keymap_parent (submap_parent, 0);
415
416 if (KEYMAPP (tem))
417 {
418 if (keymap_memberp (tem, parent_entry))
419 /* Fset_keymap_parent could create a cycle. */
420 return;
421 submap_parent = tem;
422 }
423 else
424 break;
425 }
426 Fset_keymap_parent (submap_parent, parent_entry);
427 }
428} 371}
429 372
373
430/* Look up IDX in MAP. IDX may be any sort of event. 374/* Look up IDX in MAP. IDX may be any sort of event.
431 Note that this does only one level of lookup; IDX must be a single 375 Note that this does only one level of lookup; IDX must be a single
432 event, not a sequence. 376 event, not a sequence.
433 377
378 MAP must be a keymap or a list of keymaps.
379
434 If T_OK is non-zero, bindings for Qt are treated as default 380 If T_OK is non-zero, bindings for Qt are treated as default
435 bindings; any key left unmentioned by other tables and bindings is 381 bindings; any key left unmentioned by other tables and bindings is
436 given the binding of Qt. 382 given the binding of Qt.
437 383
438 If T_OK is zero, bindings for Qt are not treated specially. 384 If T_OK is zero, bindings for Qt are not treated specially.
439 385
440 If NOINHERIT, don't accept a subkeymap found in an inherited keymap. */ 386 If NOINHERIT, don't accept a subkeymap found in an inherited keymap.
441
442Lisp_Object
443access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int autoload)
444{
445 Lisp_Object val;
446 387
447 /* Qunbound in VAL means we have found no binding yet. */ 388 Returns Qunbound if no binding was found (and returns Qnil if a nil
448 val = Qunbound; 389 binding was found). */
449 390
391static Lisp_Object
392access_keymap_1 (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int autoload)
393{
450 /* If idx is a list (some sort of mouse click, perhaps?), 394 /* If idx is a list (some sort of mouse click, perhaps?),
451 the index we want to use is the car of the list, which 395 the index we want to use is the car of the list, which
452 ought to be a symbol. */ 396 ought to be a symbol. */
@@ -461,21 +405,21 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
461 with more than 24 bits of integer. */ 405 with more than 24 bits of integer. */
462 XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); 406 XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1)));
463 407
464 /* Handle the special meta -> esc mapping. */ 408 /* Handle the special meta -> esc mapping. */
465 if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier) 409 if (INTEGERP (idx) && XFASTINT (idx) & meta_modifier)
466 { 410 {
467 /* See if there is a meta-map. If there's none, there is 411 /* See if there is a meta-map. If there's none, there is
468 no binding for IDX, unless a default binding exists in MAP. */ 412 no binding for IDX, unless a default binding exists in MAP. */
469 struct gcpro gcpro1; 413 struct gcpro gcpro1;
470 Lisp_Object event_meta_map; 414 Lisp_Object event_meta_binding, event_meta_map;
471 GCPRO1 (map); 415 GCPRO1 (map);
472 /* A strange value in which Meta is set would cause 416 /* A strange value in which Meta is set would cause
473 infinite recursion. Protect against that. */ 417 infinite recursion. Protect against that. */
474 if (XINT (meta_prefix_char) & CHAR_META) 418 if (XINT (meta_prefix_char) & CHAR_META)
475 meta_prefix_char = make_number (27); 419 meta_prefix_char = make_number (27);
476 event_meta_map = get_keymap (access_keymap (map, meta_prefix_char, 420 event_meta_binding = access_keymap_1 (map, meta_prefix_char, t_ok,
477 t_ok, noinherit, autoload), 421 noinherit, autoload);
478 0, autoload); 422 event_meta_map = get_keymap (event_meta_binding, 0, autoload);
479 UNGCPRO; 423 UNGCPRO;
480 if (CONSP (event_meta_map)) 424 if (CONSP (event_meta_map))
481 { 425 {
@@ -486,8 +430,8 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
486 /* Set IDX to t, so that we only find a default binding. */ 430 /* Set IDX to t, so that we only find a default binding. */
487 idx = Qt; 431 idx = Qt;
488 else 432 else
489 /* We know there is no binding. */ 433 /* An explicit nil binding, or no binding at all. */
490 return Qnil; 434 return NILP (event_meta_binding) ? Qnil : Qunbound;
491 } 435 }
492 436
493 /* t_binding is where we put a default binding that applies, 437 /* t_binding is where we put a default binding that applies,
@@ -495,25 +439,52 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
495 for this key sequence. */ 439 for this key sequence. */
496 { 440 {
497 Lisp_Object tail; 441 Lisp_Object tail;
498 Lisp_Object t_binding = Qnil; 442 Lisp_Object t_binding = Qunbound;
443 Lisp_Object retval = Qunbound;
444 Lisp_Object retval_tail = Qnil;
499 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 445 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
500 446
501 GCPRO4 (map, tail, idx, t_binding); 447 GCPRO4 (tail, idx, t_binding, retval);
502 448
503 for (tail = XCDR (map); 449 for (tail = (CONSP (map) && EQ (Qkeymap, XCAR (map))) ? XCDR (map) : map;
504 (CONSP (tail) 450 (CONSP (tail)
505 || (tail = get_keymap (tail, 0, autoload), CONSP (tail))); 451 || (tail = get_keymap (tail, 0, autoload), CONSP (tail)));
506 tail = XCDR (tail)) 452 tail = XCDR (tail))
507 { 453 {
508 Lisp_Object binding; 454 /* Qunbound in VAL means we have found no binding. */
455 Lisp_Object val = Qunbound;
456 Lisp_Object binding = XCAR (tail);
457 Lisp_Object submap = get_keymap (binding, 0, autoload);
509 458
510 binding = XCAR (tail); 459 if (EQ (binding, Qkeymap))
511 if (SYMBOLP (binding)) 460 {
461 if (noinherit || NILP (retval))
462 /* If NOINHERIT, stop here, the rest is inherited. */
463 break;
464 else if (!EQ (retval, Qunbound))
465 {
466 Lisp_Object parent_entry;
467 eassert (KEYMAPP (retval));
468 parent_entry
469 = get_keymap (access_keymap_1 (tail, idx,
470 t_ok, 0, autoload),
471 0, autoload);
472 if (KEYMAPP (parent_entry))
473 {
474 if (CONSP (retval_tail))
475 XSETCDR (retval_tail, parent_entry);
476 else
477 {
478 retval_tail = Fcons (retval, parent_entry);
479 retval = Fcons (Qkeymap, retval_tail);
480 }
481 }
482 break;
483 }
484 }
485 else if (CONSP (submap))
512 { 486 {
513 /* If NOINHERIT, stop finding prefix definitions 487 val = access_keymap_1 (submap, idx, t_ok, noinherit, autoload);
514 after we pass a second occurrence of the `keymap' symbol. */
515 if (noinherit && EQ (binding, Qkeymap))
516 RETURN_UNGCPRO (Qnil);
517 } 488 }
518 else if (CONSP (binding)) 489 else if (CONSP (binding))
519 { 490 {
@@ -556,23 +527,47 @@ access_keymap (Lisp_Object map, Lisp_Object idx, int t_ok, int noinherit, int au
556 (i.e. it shadows any parent binding but not bindings in 527 (i.e. it shadows any parent binding but not bindings in
557 keymaps of lower precedence). */ 528 keymaps of lower precedence). */
558 val = Qnil; 529 val = Qnil;
530
559 val = get_keyelt (val, autoload); 531 val = get_keyelt (val, autoload);
560 if (KEYMAPP (val)) 532
561 fix_submap_inheritance (map, idx, val); 533 if (!KEYMAPP (val))
562 RETURN_UNGCPRO (val); 534 {
535 if (NILP (retval) || EQ (retval, Qunbound))
536 retval = val;
537 if (!NILP (val))
538 break; /* Shadows everything that follows. */
539 }
540 else if (NILP (retval) || EQ (retval, Qunbound))
541 retval = val;
542 else if (CONSP (retval_tail))
543 {
544 XSETCDR (retval_tail, Fcons (val, Qnil));
545 retval_tail = XCDR (retval_tail);
546 }
547 else
548 {
549 retval_tail = Fcons (val, Qnil);
550 retval = Fcons (Qkeymap, Fcons (retval, retval_tail));
551 }
563 } 552 }
564 QUIT; 553 QUIT;
565 } 554 }
566 UNGCPRO; 555 UNGCPRO;
567 return get_keyelt (t_binding, autoload); 556 return EQ (Qunbound, retval) ? get_keyelt (t_binding, autoload) : retval;
568 } 557 }
569} 558}
570 559
560Lisp_Object
561access_keymap (Lisp_Object map, Lisp_Object idx,
562 int t_ok, int noinherit, int autoload)
563{
564 Lisp_Object val = access_keymap_1 (map, idx, t_ok, noinherit, autoload);
565 return EQ (val, Qunbound) ? Qnil : val;
566}
567
571static void 568static void
572map_keymap_item (map_keymap_function_t fun, Lisp_Object args, Lisp_Object key, Lisp_Object val, void *data) 569map_keymap_item (map_keymap_function_t fun, Lisp_Object args, Lisp_Object key, Lisp_Object val, void *data)
573{ 570{
574 /* We should maybe try to detect bindings shadowed by previous
575 ones and things like that. */
576 if (EQ (val, Qt)) 571 if (EQ (val, Qt))
577 val = Qnil; 572 val = Qnil;
578 (*fun) (key, val, args, data); 573 (*fun) (key, val, args, data);
@@ -583,8 +578,8 @@ map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val)
583{ 578{
584 if (!NILP (val)) 579 if (!NILP (val))
585 { 580 {
586 map_keymap_function_t fun = 581 map_keymap_function_t fun
587 (map_keymap_function_t) XSAVE_VALUE (XCAR (args))->pointer; 582 = (map_keymap_function_t) XSAVE_VALUE (XCAR (args))->pointer;
588 args = XCDR (args); 583 args = XCDR (args);
589 /* If the key is a range, make a copy since map_char_table modifies 584 /* If the key is a range, make a copy since map_char_table modifies
590 it in place. */ 585 it in place. */
@@ -612,7 +607,9 @@ map_keymap_internal (Lisp_Object map,
612 { 607 {
613 Lisp_Object binding = XCAR (tail); 608 Lisp_Object binding = XCAR (tail);
614 609
615 if (CONSP (binding)) 610 if (KEYMAPP (binding)) /* An embedded parent. */
611 break;
612 else if (CONSP (binding))
616 map_keymap_item (fun, args, XCAR (binding), XCDR (binding), data); 613 map_keymap_item (fun, args, XCAR (binding), XCDR (binding), data);
617 else if (VECTORP (binding)) 614 else if (VECTORP (binding))
618 { 615 {
@@ -644,7 +641,7 @@ map_keymap_call (Lisp_Object key, Lisp_Object val, Lisp_Object fun, void *dummy)
644 call2 (fun, key, val); 641 call2 (fun, key, val);
645} 642}
646 643
647/* Same as map_keymap_internal, but doesn't traverses parent keymaps as well. 644/* Same as map_keymap_internal, but traverses parent keymaps as well.
648 A non-zero AUTOLOAD indicates that autoloaded keymaps should be loaded. */ 645 A non-zero AUTOLOAD indicates that autoloaded keymaps should be loaded. */
649void 646void
650map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void *data, int autoload) 647map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void *data, int autoload)
@@ -654,8 +651,15 @@ map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void *
654 map = get_keymap (map, 1, autoload); 651 map = get_keymap (map, 1, autoload);
655 while (CONSP (map)) 652 while (CONSP (map))
656 { 653 {
657 map = map_keymap_internal (map, fun, args, data); 654 if (KEYMAPP (XCAR (map)))
658 map = get_keymap (map, 0, autoload); 655 {
656 map_keymap (XCAR (map), fun, args, data, autoload);
657 map = XCDR (map);
658 }
659 else
660 map = map_keymap_internal (map, fun, args, data);
661 if (!CONSP (map))
662 map = get_keymap (map, 0, autoload);
659 } 663 }
660 UNGCPRO; 664 UNGCPRO;
661} 665}
@@ -791,16 +795,10 @@ get_keyelt (Lisp_Object object, int autoload)
791 } 795 }
792 796
793 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ 797 /* If the contents are (KEYMAP . ELEMENT), go indirect. */
798 else if (KEYMAPP (XCAR (object)))
799 error ("Wow, indirect keymap entry!!");
794 else 800 else
795 { 801 return object;
796 struct gcpro gcpro1;
797 Lisp_Object map;
798 GCPRO1 (object);
799 map = get_keymap (Fcar_safe (object), 0, autoload);
800 UNGCPRO;
801 return (!CONSP (map) ? object /* Invalid keymap */
802 : access_keymap (map, Fcdr (object), 0, 0, autoload));
803 }
804 } 802 }
805} 803}
806 804
@@ -811,6 +809,9 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
811 where_is_cache = Qnil; 809 where_is_cache = Qnil;
812 where_is_cache_keymaps = Qt; 810 where_is_cache_keymaps = Qt;
813 811
812 if (EQ (idx, Qkeymap))
813 error ("`keymap' is reserved for embedded parent maps");
814
814 /* If we are preparing to dump, and DEF is a menu element 815 /* If we are preparing to dump, and DEF is a menu element
815 with a menu item indicator, copy it to ensure it is not pure. */ 816 with a menu item indicator, copy it to ensure it is not pure. */
816 if (CONSP (def) && PURE_P (def) 817 if (CONSP (def) && PURE_P (def)
@@ -903,7 +904,16 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
903 } 904 }
904 else if (CONSP (elt)) 905 else if (CONSP (elt))
905 { 906 {
906 if (EQ (idx, XCAR (elt))) 907 if (EQ (Qkeymap, XCAR (elt)))
908 { /* A sub keymap. This might be due to a lookup that found
909 two matching bindings (maybe because of a sub keymap).
910 It almost never happens (since the second binding normally
911 only happens in the inherited part of the keymap), but
912 if it does, we want to update the sub-keymap since the
913 main one might be temporary (built by access_keymap). */
914 tail = insertion_point = elt;
915 }
916 else if (EQ (idx, XCAR (elt)))
907 { 917 {
908 CHECK_IMPURE (elt); 918 CHECK_IMPURE (elt);
909 XSETCDR (elt, def); 919 XSETCDR (elt, def);
@@ -1068,7 +1078,13 @@ is not copied. */)
1068 ASET (elt, i, copy_keymap_item (AREF (elt, i))); 1078 ASET (elt, i, copy_keymap_item (AREF (elt, i)));
1069 } 1079 }
1070 else if (CONSP (elt)) 1080 else if (CONSP (elt))
1071 elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt))); 1081 {
1082 if (EQ (XCAR (elt), Qkeymap))
1083 /* This is a sub keymap. */
1084 elt = Fcopy_keymap (elt);
1085 else
1086 elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt)));
1087 }
1072 XSETCDR (tail, Fcons (elt, Qnil)); 1088 XSETCDR (tail, Fcons (elt, Qnil));
1073 tail = XCDR (tail); 1089 tail = XCDR (tail);
1074 keymap = XCDR (keymap); 1090 keymap = XCDR (keymap);
@@ -1234,23 +1250,15 @@ remapping in all currently active keymaps. */)
1234 ASET (command_remapping_vector, 1, command); 1250 ASET (command_remapping_vector, 1, command);
1235 1251
1236 if (NILP (keymaps)) 1252 if (NILP (keymaps))
1237 return Fkey_binding (command_remapping_vector, Qnil, Qt, position); 1253 command = Fkey_binding (command_remapping_vector, Qnil, Qt, position);
1238 else 1254 else
1239 { 1255 command = Flookup_key (Fcons (Qkeymap, keymaps),
1240 Lisp_Object maps, binding; 1256 command_remapping_vector, Qnil);
1241 1257 return INTEGERP (command) ? Qnil : command;
1242 for (maps = keymaps; CONSP (maps); maps = XCDR (maps))
1243 {
1244 binding = Flookup_key (XCAR (maps), command_remapping_vector, Qnil);
1245 if (!NILP (binding) && !INTEGERP (binding))
1246 return binding;
1247 }
1248 return Qnil;
1249 }
1250} 1258}
1251 1259
1252/* Value is number if KEY is too long; nil if valid but has no definition. */ 1260/* Value is number if KEY is too long; nil if valid but has no definition. */
1253/* GC is possible in this function if it autoloads a keymap. */ 1261/* GC is possible in this function. */
1254 1262
1255DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0, 1263DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
1256 doc: /* In keymap KEYMAP, look up key sequence KEY. Return the definition. 1264 doc: /* In keymap KEYMAP, look up key sequence KEY. Return the definition.
@@ -1325,10 +1333,6 @@ define_as_prefix (Lisp_Object keymap, Lisp_Object c)
1325 Lisp_Object cmd; 1333 Lisp_Object cmd;
1326 1334
1327 cmd = Fmake_sparse_keymap (Qnil); 1335 cmd = Fmake_sparse_keymap (Qnil);
1328 /* If this key is defined as a prefix in an inherited keymap,
1329 make it a prefix in this map, and make its definition
1330 inherit the other prefix definition. */
1331 cmd = nconc2 (cmd, access_keymap (keymap, c, 0, 0, 0));
1332 store_in_keymap (keymap, c, cmd); 1336 store_in_keymap (keymap, c, cmd);
1333 1337
1334 return cmd; 1338 return cmd;
@@ -1530,7 +1534,7 @@ like in the respective argument of `key-binding'. */)
1530{ 1534{
1531 int count = SPECPDL_INDEX (); 1535 int count = SPECPDL_INDEX ();
1532 1536
1533 Lisp_Object keymaps; 1537 Lisp_Object keymaps = Fcons (current_global_map, Qnil);
1534 1538
1535 /* If a mouse click position is given, our variables are based on 1539 /* If a mouse click position is given, our variables are based on
1536 the buffer clicked on, not the current buffer. So we may have to 1540 the buffer clicked on, not the current buffer. So we may have to
@@ -1560,12 +1564,11 @@ like in the respective argument of `key-binding'. */)
1560 } 1564 }
1561 } 1565 }
1562 1566
1563 keymaps = Fcons (current_global_map, Qnil);
1564
1565 if (!NILP (olp)) 1567 if (!NILP (olp))
1566 { 1568 {
1567 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map))) 1569 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
1568 keymaps = Fcons (KVAR (current_kboard, Voverriding_terminal_local_map), keymaps); 1570 keymaps = Fcons (KVAR (current_kboard, Voverriding_terminal_local_map),
1571 keymaps);
1569 /* The doc said that overriding-terminal-local-map should 1572 /* The doc said that overriding-terminal-local-map should
1570 override overriding-local-map. The code used them both, 1573 override overriding-local-map. The code used them both,
1571 but it seems clearer to use just one. rms, jan 2005. */ 1574 but it seems clearer to use just one. rms, jan 2005. */
@@ -1576,23 +1579,19 @@ like in the respective argument of `key-binding'. */)
1576 { 1579 {
1577 Lisp_Object *maps; 1580 Lisp_Object *maps;
1578 int nmaps, i; 1581 int nmaps, i;
1579 1582 EMACS_INT pt
1580 Lisp_Object keymap, local_map; 1583 = INTEGERP (position) ? XINT (position)
1581 EMACS_INT pt;
1582
1583 pt = INTEGERP (position) ? XINT (position)
1584 : MARKERP (position) ? marker_position (position) 1584 : MARKERP (position) ? marker_position (position)
1585 : PT; 1585 : PT;
1586 1586 /* This usually returns the buffer's local map,
1587 /* Get the buffer local maps, possibly overriden by text or 1587 but that can be overridden by a `local-map' property. */
1588 overlay properties */ 1588 Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map);
1589 1589 /* This returns nil unless there is a `keymap' property. */
1590 local_map = get_local_map (pt, current_buffer, Qlocal_map); 1590 Lisp_Object keymap = get_local_map (pt, current_buffer, Qkeymap);
1591 keymap = get_local_map (pt, current_buffer, Qkeymap);
1592 1591
1593 if (CONSP (position)) 1592 if (CONSP (position))
1594 { 1593 {
1595 Lisp_Object string; 1594 Lisp_Object string = POSN_STRING (position);
1596 1595
1597 /* For a mouse click, get the local text-property keymap 1596 /* For a mouse click, get the local text-property keymap
1598 of the place clicked on, rather than point. */ 1597 of the place clicked on, rather than point. */
@@ -1619,8 +1618,7 @@ like in the respective argument of `key-binding'. */)
1619 consider `local-map' and `keymap' properties of 1618 consider `local-map' and `keymap' properties of
1620 that string. */ 1619 that string. */
1621 1620
1622 if (string = POSN_STRING (position), 1621 if (CONSP (string) && STRINGP (XCAR (string)))
1623 (CONSP (string) && STRINGP (XCAR (string))))
1624 { 1622 {
1625 Lisp_Object pos, map; 1623 Lisp_Object pos, map;
1626 1624
@@ -1691,12 +1689,7 @@ specified buffer position instead of point are used.
1691 */) 1689 */)
1692 (Lisp_Object key, Lisp_Object accept_default, Lisp_Object no_remap, Lisp_Object position) 1690 (Lisp_Object key, Lisp_Object accept_default, Lisp_Object no_remap, Lisp_Object position)
1693{ 1691{
1694 Lisp_Object *maps, value; 1692 Lisp_Object value;
1695 int nmaps, i;
1696 struct gcpro gcpro1, gcpro2;
1697 int count = SPECPDL_INDEX ();
1698
1699 GCPRO2 (key, position);
1700 1693
1701 if (NILP (position) && VECTORP (key)) 1694 if (NILP (position) && VECTORP (key))
1702 { 1695 {
@@ -1715,145 +1708,9 @@ specified buffer position instead of point are used.
1715 } 1708 }
1716 } 1709 }
1717 1710
1718 /* Key sequences beginning with mouse clicks 1711 value = Flookup_key (Fcons (Qkeymap, Fcurrent_active_maps (Qt, position)),
1719 are read using the keymaps of the buffer clicked on, not 1712 key, accept_default);
1720 the current buffer. So we may have to switch the buffer
1721 here. */
1722
1723 if (CONSP (position))
1724 {
1725 Lisp_Object window;
1726 1713
1727 window = POSN_WINDOW (position);
1728
1729 if (WINDOWP (window)
1730 && BUFFERP (XWINDOW (window)->buffer)
1731 && XBUFFER (XWINDOW (window)->buffer) != current_buffer)
1732 {
1733 /* Arrange to go back to the original buffer once we're done
1734 processing the key sequence. We don't use
1735 save_excursion_{save,restore} here, in analogy to
1736 `read-key-sequence' to avoid saving point. Maybe this
1737 would not be a problem here, but it is easier to keep
1738 things the same.
1739 */
1740
1741 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1742
1743 set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
1744 }
1745 }
1746
1747 if (! NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
1748 {
1749 value = Flookup_key (KVAR (current_kboard, Voverriding_terminal_local_map),
1750 key, accept_default);
1751 if (! NILP (value) && !INTEGERP (value))
1752 goto done;
1753 }
1754 else if (! NILP (Voverriding_local_map))
1755 {
1756 value = Flookup_key (Voverriding_local_map, key, accept_default);
1757 if (! NILP (value) && !INTEGERP (value))
1758 goto done;
1759 }
1760 else
1761 {
1762 Lisp_Object keymap, local_map;
1763 EMACS_INT pt;
1764
1765 pt = INTEGERP (position) ? XINT (position)
1766 : MARKERP (position) ? marker_position (position)
1767 : PT;
1768
1769 local_map = get_local_map (pt, current_buffer, Qlocal_map);
1770 keymap = get_local_map (pt, current_buffer, Qkeymap);
1771
1772 if (CONSP (position))
1773 {
1774 Lisp_Object string;
1775
1776 /* For a mouse click, get the local text-property keymap
1777 of the place clicked on, rather than point. */
1778
1779 if (POSN_INBUFFER_P (position))
1780 {
1781 Lisp_Object pos;
1782
1783 pos = POSN_BUFFER_POSN (position);
1784 if (INTEGERP (pos)
1785 && XINT (pos) >= BEG && XINT (pos) <= Z)
1786 {
1787 local_map = get_local_map (XINT (pos),
1788 current_buffer, Qlocal_map);
1789
1790 keymap = get_local_map (XINT (pos),
1791 current_buffer, Qkeymap);
1792 }
1793 }
1794
1795 /* If on a mode line string with a local keymap,
1796 or for a click on a string, i.e. overlay string or a
1797 string displayed via the `display' property,
1798 consider `local-map' and `keymap' properties of
1799 that string. */
1800
1801 if (string = POSN_STRING (position),
1802 (CONSP (string) && STRINGP (XCAR (string))))
1803 {
1804 Lisp_Object pos, map;
1805
1806 pos = XCDR (string);
1807 string = XCAR (string);
1808 if (INTEGERP (pos)
1809 && XINT (pos) >= 0
1810 && XINT (pos) < SCHARS (string))
1811 {
1812 map = Fget_text_property (pos, Qlocal_map, string);
1813 if (!NILP (map))
1814 local_map = map;
1815
1816 map = Fget_text_property (pos, Qkeymap, string);
1817 if (!NILP (map))
1818 keymap = map;
1819 }
1820 }
1821
1822 }
1823
1824 if (! NILP (keymap))
1825 {
1826 value = Flookup_key (keymap, key, accept_default);
1827 if (! NILP (value) && !INTEGERP (value))
1828 goto done;
1829 }
1830
1831 nmaps = current_minor_maps (0, &maps);
1832 /* Note that all these maps are GCPRO'd
1833 in the places where we found them. */
1834
1835 for (i = 0; i < nmaps; i++)
1836 if (! NILP (maps[i]))
1837 {
1838 value = Flookup_key (maps[i], key, accept_default);
1839 if (! NILP (value) && !INTEGERP (value))
1840 goto done;
1841 }
1842
1843 if (! NILP (local_map))
1844 {
1845 value = Flookup_key (local_map, key, accept_default);
1846 if (! NILP (value) && !INTEGERP (value))
1847 goto done;
1848 }
1849 }
1850
1851 value = Flookup_key (current_global_map, key, accept_default);
1852
1853 done:
1854 unbind_to (count, Qnil);
1855
1856 UNGCPRO;
1857 if (NILP (value) || INTEGERP (value)) 1714 if (NILP (value) || INTEGERP (value))
1858 return Qnil; 1715 return Qnil;
1859 1716
@@ -3094,9 +2951,11 @@ You type Translation\n\
3094 to look through. 2951 to look through.
3095 2952
3096 If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW, 2953 If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW,
3097 don't omit it; instead, mention it but say it is shadowed. */ 2954 don't omit it; instead, mention it but say it is shadowed.
3098 2955
3099void 2956 Return whether something was inserted or not. */
2957
2958int
3100describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow, 2959describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow,
3101 Lisp_Object prefix, const char *title, int nomenu, int transl, 2960 Lisp_Object prefix, const char *title, int nomenu, int transl,
3102 int always_title, int mention_shadow) 2961 int always_title, int mention_shadow)
@@ -3206,10 +3065,8 @@ key binding\n\
3206 skip: ; 3065 skip: ;
3207 } 3066 }
3208 3067
3209 if (something)
3210 insert_string ("\n");
3211
3212 UNGCPRO; 3068 UNGCPRO;
3069 return something;
3213} 3070}
3214 3071
3215static int previous_description_column; 3072static int previous_description_column;
@@ -3829,31 +3686,6 @@ don't alter it yourself. */);
3829 Vminibuffer_local_ns_map = Fmake_sparse_keymap (Qnil); 3686 Vminibuffer_local_ns_map = Fmake_sparse_keymap (Qnil);
3830 Fset_keymap_parent (Vminibuffer_local_ns_map, Vminibuffer_local_map); 3687 Fset_keymap_parent (Vminibuffer_local_ns_map, Vminibuffer_local_map);
3831 3688
3832 DEFVAR_LISP ("minibuffer-local-completion-map", Vminibuffer_local_completion_map,
3833 doc: /* Local keymap for minibuffer input with completion. */);
3834 Vminibuffer_local_completion_map = Fmake_sparse_keymap (Qnil);
3835 Fset_keymap_parent (Vminibuffer_local_completion_map, Vminibuffer_local_map);
3836
3837 DEFVAR_LISP ("minibuffer-local-filename-completion-map",
3838 Vminibuffer_local_filename_completion_map,
3839 doc: /* Local keymap for minibuffer input with completion for filenames. */);
3840 Vminibuffer_local_filename_completion_map = Fmake_sparse_keymap (Qnil);
3841 Fset_keymap_parent (Vminibuffer_local_filename_completion_map,
3842 Vminibuffer_local_completion_map);
3843
3844
3845 DEFVAR_LISP ("minibuffer-local-must-match-map", Vminibuffer_local_must_match_map,
3846 doc: /* Local keymap for minibuffer input with completion, for exact match. */);
3847 Vminibuffer_local_must_match_map = Fmake_sparse_keymap (Qnil);
3848 Fset_keymap_parent (Vminibuffer_local_must_match_map,
3849 Vminibuffer_local_completion_map);
3850
3851 DEFVAR_LISP ("minibuffer-local-filename-must-match-map",
3852 Vminibuffer_local_filename_must_match_map,
3853 doc: /* Local keymap for minibuffer input with completion for filenames with exact match. */);
3854 Vminibuffer_local_filename_must_match_map = Fmake_sparse_keymap (Qnil);
3855 Fset_keymap_parent (Vminibuffer_local_filename_must_match_map,
3856 Vminibuffer_local_must_match_map);
3857 3689
3858 DEFVAR_LISP ("minor-mode-map-alist", Vminor_mode_map_alist, 3690 DEFVAR_LISP ("minor-mode-map-alist", Vminor_mode_map_alist,
3859 doc: /* Alist of keymaps to use for minor modes. 3691 doc: /* Alist of keymaps to use for minor modes.
@@ -3880,11 +3712,11 @@ the same way. The "active" keymaps in each alist are used before
3880 Vemulation_mode_map_alists = Qnil; 3712 Vemulation_mode_map_alists = Qnil;
3881 3713
3882 DEFVAR_LISP ("where-is-preferred-modifier", Vwhere_is_preferred_modifier, 3714 DEFVAR_LISP ("where-is-preferred-modifier", Vwhere_is_preferred_modifier,
3883 doc: /* Preferred modifier to use for `where-is'. 3715 doc: /* Preferred modifier key to use for `where-is'.
3884When a single binding is requested, `where-is' will return one that 3716When a single binding is requested, `where-is' will return one that
3885uses this modifier if possible. If nil, or if no such binding exists, 3717uses this modifier key if possible. If nil, or if no such binding
3886bindings using keys without modifiers (or only with meta) will be 3718exists, bindings using keys without modifiers (or only with meta) will
3887preferred. */); 3719be preferred. */);
3888 Vwhere_is_preferred_modifier = Qnil; 3720 Vwhere_is_preferred_modifier = Qnil;
3889 where_is_preferred_modifier = 0; 3721 where_is_preferred_modifier = 0;
3890 3722
@@ -3922,6 +3754,7 @@ preferred. */);
3922 defsubr (&Sset_keymap_parent); 3754 defsubr (&Sset_keymap_parent);
3923 defsubr (&Smake_keymap); 3755 defsubr (&Smake_keymap);
3924 defsubr (&Smake_sparse_keymap); 3756 defsubr (&Smake_sparse_keymap);
3757 defsubr (&Smake_composed_keymap);
3925 defsubr (&Smap_keymap_internal); 3758 defsubr (&Smap_keymap_internal);
3926 defsubr (&Smap_keymap); 3759 defsubr (&Smap_keymap);
3927 defsubr (&Scopy_keymap); 3760 defsubr (&Scopy_keymap);
diff --git a/src/keymap.h b/src/keymap.h
index 2b9d58b39dc..2c826b64e1f 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -36,8 +36,8 @@ EXFUN (Fcurrent_active_maps, 2);
36extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, int, int, int); 36extern Lisp_Object access_keymap (Lisp_Object, Lisp_Object, int, int, int);
37extern Lisp_Object get_keymap (Lisp_Object, int, int); 37extern Lisp_Object get_keymap (Lisp_Object, int, int);
38EXFUN (Fset_keymap_parent, 2); 38EXFUN (Fset_keymap_parent, 2);
39extern void describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object, 39extern int describe_map_tree (Lisp_Object, int, Lisp_Object, Lisp_Object,
40 const char *, int, int, int, int); 40 const char *, int, int, int, int);
41extern int current_minor_maps (Lisp_Object **, Lisp_Object **); 41extern int current_minor_maps (Lisp_Object **, Lisp_Object **);
42extern void initial_define_key (Lisp_Object, int, const char *); 42extern void initial_define_key (Lisp_Object, int, const char *);
43extern void initial_define_lispy_key (Lisp_Object, const char *, const char *); 43extern void initial_define_lispy_key (Lisp_Object, const char *, const char *);
diff --git a/src/lread.c b/src/lread.c
index f937fa39f0f..6cb217a21c6 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4000,9 +4000,7 @@ defsubr (struct Lisp_Subr *sname)
4000 4000
4001#ifdef NOTDEF /* use fset in subr.el now */ 4001#ifdef NOTDEF /* use fset in subr.el now */
4002void 4002void
4003defalias (sname, string) 4003defalias (struct Lisp_Subr *sname, char *string)
4004 struct Lisp_Subr *sname;
4005 char *string;
4006{ 4004{
4007 Lisp_Object sym; 4005 Lisp_Object sym;
4008 sym = intern (string); 4006 sym = intern (string);
@@ -4420,9 +4418,11 @@ The remaining ENTRIES in the alist element describe the functions and
4420variables defined in that file, the features provided, and the 4418variables defined in that file, the features provided, and the
4421features required. Each entry has the form `(provide . FEATURE)', 4419features required. Each entry has the form `(provide . FEATURE)',
4422`(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)', 4420`(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)',
4423`(defface . SYMBOL)', or `(t . SYMBOL)'. In addition, an entry `(t 4421`(defface . SYMBOL)', or `(t . SYMBOL)'. Entries like `(t . SYMBOL)'
4424. SYMBOL)' may precede an entry `(defun . FUNCTION)', and means that 4422may precede a `(defun . FUNCTION)' entry, and means that SYMBOL was an
4425SYMBOL was an autoload before this file redefined it as a function. 4423autoload before this file redefined it as a function. In addition,
4424entries may also be single symbols, which means that SYMBOL was
4425defined by `defvar' or `defconst'.
4426 4426
4427During preloading, the file name recorded is relative to the main Lisp 4427During preloading, the file name recorded is relative to the main Lisp
4428directory. These file names are converted to absolute at startup. */); 4428directory. These file names are converted to absolute at startup. */);
diff --git a/src/m/iris4d.h b/src/m/iris4d.h
deleted file mode 100644
index 881f71f846f..00000000000
--- a/src/m/iris4d.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/* machine description file for Iris-4D machines. Use with s/irix*.h.
2
3Copyright (C) 1987, 2001-2011 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20
21/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which
22 were stored in a Lisp_Object (as Emacs uses fewer than 32 bits for
23 the value field of a LISP_OBJECT). */
24#define DATA_START 0x10000000
25#define DATA_SEG_BITS 0x10000000
26
diff --git a/src/nsfns.m b/src/nsfns.m
index cdf350066be..0452086201e 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -162,7 +162,7 @@ check_ns_display_info (Lisp_Object frame)
162 struct terminal *t = get_terminal (frame, 1); 162 struct terminal *t = get_terminal (frame, 1);
163 163
164 if (t->type != output_ns) 164 if (t->type != output_ns)
165 error ("Terminal %d is not a Nextstep display", XINT (frame)); 165 error ("Terminal %ld is not a Nextstep display", (long) XINT (frame));
166 166
167 return t->display_info.ns; 167 return t->display_info.ns;
168 } 168 }
@@ -1728,8 +1728,9 @@ terminate Emacs if we can't open the connection.
1728 1728
1729 /* Register our external input/output types, used for determining 1729 /* Register our external input/output types, used for determining
1730 applicable services and also drag/drop eligibility. */ 1730 applicable services and also drag/drop eligibility. */
1731 ns_send_types = [[NSArray arrayWithObject: NSStringPboardType] retain]; 1731 ns_send_types = [[NSArray arrayWithObjects: NSStringPboardType, nil] retain];
1732 ns_return_types = [[NSArray arrayWithObject: NSStringPboardType] retain]; 1732 ns_return_types = [[NSArray arrayWithObjects: NSStringPboardType, nil]
1733 retain];
1733 ns_drag_types = [[NSArray arrayWithObjects: 1734 ns_drag_types = [[NSArray arrayWithObjects:
1734 NSStringPboardType, 1735 NSStringPboardType,
1735 NSTabularTextPboardType, 1736 NSTabularTextPboardType,
@@ -1876,6 +1877,10 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
1876 doc: /* List available Nextstep services by querying NSApp. */) 1877 doc: /* List available Nextstep services by querying NSApp. */)
1877 (void) 1878 (void)
1878{ 1879{
1880#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
1881 /* You can't get services like this in 10.6+. */
1882 return Qnil;
1883#else
1879 Lisp_Object ret = Qnil; 1884 Lisp_Object ret = Qnil;
1880 NSMenu *svcs; 1885 NSMenu *svcs;
1881 id delegate; 1886 id delegate;
@@ -1919,6 +1924,7 @@ DEFUN ("ns-list-services", Fns_list_services, Sns_list_services, 0, 0, 0,
1919 1924
1920 ret = interpret_services_menu (svcs, Qnil, ret); 1925 ret = interpret_services_menu (svcs, Qnil, ret);
1921 return ret; 1926 return ret;
1927#endif
1922} 1928}
1923 1929
1924 1930
diff --git a/src/nsgui.h b/src/nsgui.h
index a6955630941..999dc27e310 100644
--- a/src/nsgui.h
+++ b/src/nsgui.h
@@ -30,6 +30,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#undef init_process 30#undef init_process
31#endif /* NS_IMPL_COCOA */ 31#endif /* NS_IMPL_COCOA */
32 32
33#undef verify
34
33#import <AppKit/AppKit.h> 35#import <AppKit/AppKit.h>
34 36
35#ifdef NS_IMPL_COCOA 37#ifdef NS_IMPL_COCOA
@@ -44,6 +46,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
44 46
45#endif /* __OBJC__ */ 47#endif /* __OBJC__ */
46 48
49#undef verify
50#undef _GL_VERIFY_H
51#include <verify.h>
47 52
48/* menu-related */ 53/* menu-related */
49#define free_widget_value(wv) xfree (wv) 54#define free_widget_value(wv) xfree (wv)
diff --git a/src/nsimage.m b/src/nsimage.m
index c38cefdc5d5..2cb0c3bff76 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -189,7 +189,11 @@ static EmacsImage *ImageList = nil;
189 image = [[EmacsImage alloc] initByReferencingFile: 189 image = [[EmacsImage alloc] initByReferencingFile:
190 [NSString stringWithUTF8String: SDATA (found)]]; 190 [NSString stringWithUTF8String: SDATA (found)]];
191 191
192#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
193 imgRep = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
194#else
192 imgRep = [image bestRepresentationForDevice: nil]; 195 imgRep = [image bestRepresentationForDevice: nil];
196#endif
193 if (imgRep == nil) 197 if (imgRep == nil)
194 { 198 {
195 [image release]; 199 [image release];
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 2a2f952e751..6a9ee7dd4f5 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -457,7 +457,6 @@ ns_update_menubar (struct frame *f, int deep_p, EmacsMenu *submenu)
457 { 457 {
458 /* but we need to make sure it will update on demand */ 458 /* but we need to make sure it will update on demand */
459 [svcsMenu setFrame: f]; 459 [svcsMenu setFrame: f];
460 [svcsMenu setDelegate: svcsMenu];
461 } 460 }
462 else 461 else
463#endif 462#endif
@@ -696,9 +695,11 @@ set_frame_menubar (struct frame *f, int first_time, int deep_p)
696 if ([[self window] isVisible]) 695 if ([[self window] isVisible])
697 [self sizeToFit]; 696 [self sizeToFit];
698#else 697#else
698#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2
699 if ([self supermenu] == nil) 699 if ([self supermenu] == nil)
700 [self sizeToFit]; 700 [self sizeToFit];
701#endif 701#endif
702#endif
702} 703}
703 704
704 705
diff --git a/src/nsselect.m b/src/nsselect.m
index 950fb1f1f14..867cf3252e5 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -175,7 +175,7 @@ ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype)
175} 175}
176 176
177 177
178static Lisp_Object 178Lisp_Object
179ns_get_local_selection (Lisp_Object selection_name, 179ns_get_local_selection (Lisp_Object selection_name,
180 Lisp_Object target_type) 180 Lisp_Object target_type)
181{ 181{
@@ -352,16 +352,22 @@ ns_string_from_pasteboard (id pb)
352 utfStr = [mstr UTF8String]; 352 utfStr = [mstr UTF8String];
353 length = [mstr lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; 353 length = [mstr lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
354 354
355#if ! defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
355 if (!utfStr) 356 if (!utfStr)
356 { 357 {
357 utfStr = [mstr cString]; 358 utfStr = [mstr cString];
358 length = strlen (utfStr); 359 length = strlen (utfStr);
359 } 360 }
361#endif
360 } 362 }
361 NS_HANDLER 363 NS_HANDLER
362 { 364 {
363 message1 ("ns_string_from_pasteboard: UTF8String failed\n"); 365 message1 ("ns_string_from_pasteboard: UTF8String failed\n");
366#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
367 utfStr = "Conversion failed";
368#else
364 utfStr = [str lossyCString]; 369 utfStr = [str lossyCString];
370#endif
365 length = strlen (utfStr); 371 length = strlen (utfStr);
366 } 372 }
367 NS_ENDHANDLER 373 NS_ENDHANDLER
diff --git a/src/nsterm.h b/src/nsterm.h
index 7459087c988..f419391a11e 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -25,6 +25,21 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 25
26#ifdef HAVE_NS 26#ifdef HAVE_NS
27 27
28#ifdef NS_IMPL_COCOA
29#ifndef MAC_OS_X_VERSION_10_3
30#define MAC_OS_X_VERSION_10_3 1030
31#endif
32#ifndef MAC_OS_X_VERSION_10_4
33#define MAC_OS_X_VERSION_10_4 1040
34#endif
35#ifndef MAC_OS_X_VERSION_10_5
36#define MAC_OS_X_VERSION_10_5 1050
37#endif
38#ifndef MAC_OS_X_VERSION_10_6
39#define MAC_OS_X_VERSION_10_6 1060
40#endif
41#endif /* NS_IMPL_COCOA */
42
28#ifdef __OBJC__ 43#ifdef __OBJC__
29 44
30/* ========================================================================== 45/* ==========================================================================
@@ -55,7 +70,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
55 70
56@class EmacsToolbar; 71@class EmacsToolbar;
57 72
58@interface EmacsView : NSView <NSTextInput> /* 10.6+: NSWindowDelegate */ 73#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
74@interface EmacsView : NSView <NSTextInput, NSWindowDelegate>
75#else
76@interface EmacsView : NSView <NSTextInput>
77#endif
59 { 78 {
60 char *old_title; 79 char *old_title;
61 BOOL windowClosing; 80 BOOL windowClosing;
@@ -106,7 +125,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
106 125
107 ========================================================================== */ 126 ========================================================================== */
108 127
109@interface EmacsMenu : NSMenu /* 10.6+: <NSMenuDelegate> */ 128#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
129@interface EmacsMenu : NSMenu <NSMenuDelegate>
130#else
131@interface EmacsMenu : NSMenu
132#endif
110{ 133{
111 struct frame *frame; 134 struct frame *frame;
112 unsigned long keyEquivModMask; 135 unsigned long keyEquivModMask;
@@ -133,7 +156,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
133 156
134@class EmacsImage; 157@class EmacsImage;
135 158
136@interface EmacsToolbar : NSToolbar /* 10.6+: <NSToolbarDelegate> */ 159#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
160@interface EmacsToolbar : NSToolbar <NSToolbarDelegate>
161#else
162@interface EmacsToolbar : NSToolbar
163#endif
137 { 164 {
138 EmacsView *emacsView; 165 EmacsView *emacsView;
139 NSMutableDictionary *identifierToItem; 166 NSMutableDictionary *identifierToItem;
@@ -176,7 +203,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
176- (Lisp_Object)runDialogAt: (NSPoint)p; 203- (Lisp_Object)runDialogAt: (NSPoint)p;
177@end 204@end
178 205
179@interface EmacsTooltip : NSObject /* 10.6+: <NSWindowDelegate> */ 206#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
207@interface EmacsTooltip : NSObject <NSWindowDelegate>
208#else
209@interface EmacsTooltip : NSObject
210#endif
180 { 211 {
181 NSWindow *win; 212 NSWindow *win;
182 NSTextField *textField; 213 NSTextField *textField;
@@ -700,6 +731,8 @@ extern void check_ns (void);
700extern Lisp_Object ns_map_event_to_object (); 731extern Lisp_Object ns_map_event_to_object ();
701extern Lisp_Object ns_string_from_pasteboard (); 732extern Lisp_Object ns_string_from_pasteboard ();
702extern void ns_string_to_pasteboard (); 733extern void ns_string_to_pasteboard ();
734extern Lisp_Object ns_get_local_selection (Lisp_Object selection_name,
735 Lisp_Object target_type);
703extern void nxatoms_of_nsselect (); 736extern void nxatoms_of_nsselect ();
704extern int ns_lisp_to_cursor_type (); 737extern int ns_lisp_to_cursor_type ();
705extern Lisp_Object ns_cursor_type_to_lisp (int arg); 738extern Lisp_Object ns_cursor_type_to_lisp (int arg);
diff --git a/src/nsterm.m b/src/nsterm.m
index 52e0dc6c2a8..546247ab74a 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -134,11 +134,12 @@ static unsigned convert_ns_to_X_keysym[] =
134 0x1B, 0x1B /* escape */ 134 0x1B, 0x1B /* escape */
135}; 135};
136 136
137
138static Lisp_Object Qmodifier_value; 137static Lisp_Object Qmodifier_value;
139Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone; 138Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone;
140extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft; 139extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft;
141 140
141static Lisp_Object QUTF8_STRING;
142
142/* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold, 143/* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold,
143 the maximum font size to NOT antialias. On GNUstep there is currently 144 the maximum font size to NOT antialias. On GNUstep there is currently
144 no way to control this behavior. */ 145 no way to control this behavior. */
@@ -4514,7 +4515,9 @@ ns_term_shutdown (int sig)
4514 unsigned fnKeysym = 0; 4515 unsigned fnKeysym = 0;
4515 int flags; 4516 int flags;
4516 static NSMutableArray *nsEvArray; 4517 static NSMutableArray *nsEvArray;
4518#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
4517 static BOOL firstTime = YES; 4519 static BOOL firstTime = YES;
4520#endif
4518 int left_is_none; 4521 int left_is_none;
4519 4522
4520 NSTRACE (keyDown); 4523 NSTRACE (keyDown);
@@ -4702,13 +4705,15 @@ ns_term_shutdown (int sig)
4702 } 4705 }
4703 } 4706 }
4704 4707
4708
4709#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
4705 /* if we get here we should send the key for input manager processing */ 4710 /* if we get here we should send the key for input manager processing */
4706 if (firstTime && [[NSInputManager currentInputManager] 4711 if (firstTime && [[NSInputManager currentInputManager]
4707 wantsToDelayTextChangeNotifications] == NO) 4712 wantsToDelayTextChangeNotifications] == NO)
4708 fprintf (stderr, 4713 fprintf (stderr,
4709 "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n"); 4714 "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n");
4710 firstTime = NO; 4715 firstTime = NO;
4711 4716#endif
4712 if (NS_KEYLOG && !processingCompose) 4717 if (NS_KEYLOG && !processingCompose)
4713 fprintf (stderr, "keyDown: Begin compose sequence.\n"); 4718 fprintf (stderr, "keyDown: Begin compose sequence.\n");
4714 4719
@@ -5364,6 +5369,9 @@ ns_term_shutdown (int sig)
5364 5369
5365 [self allocateGState]; 5370 [self allocateGState];
5366 5371
5372 [NSApp registerServicesMenuSendTypes: ns_send_types
5373 returnTypes: nil];
5374
5367 ns_window_num++; 5375 ns_window_num++;
5368 return self; 5376 return self;
5369} 5377}
@@ -5735,13 +5743,16 @@ ns_term_shutdown (int sig)
5735} 5743}
5736 5744
5737 5745
5738- validRequestorForSendType: (NSString *)typeSent 5746- (id) validRequestorForSendType: (NSString *)typeSent
5739 returnType: (NSString *)typeReturned 5747 returnType: (NSString *)typeReturned
5740{ 5748{
5741 NSTRACE (validRequestorForSendType); 5749 NSTRACE (validRequestorForSendType);
5742 if ([ns_send_types indexOfObjectIdenticalTo: typeSent] != NSNotFound && 5750 if (typeSent != nil && [ns_send_types indexOfObject: typeSent] != NSNotFound
5743 [ns_return_types indexOfObjectIdenticalTo: typeSent] != NSNotFound) 5751 && typeReturned == nil)
5744 return self; 5752 {
5753 if (! NILP (ns_get_local_selection (QPRIMARY, QUTF8_STRING)))
5754 return self;
5755 }
5745 5756
5746 return [super validRequestorForSendType: typeSent 5757 return [super validRequestorForSendType: typeSent
5747 returnType: typeReturned]; 5758 returnType: typeReturned];
@@ -5765,8 +5776,28 @@ ns_term_shutdown (int sig)
5765 5776
5766- (BOOL) writeSelectionToPasteboard: (NSPasteboard *)pb types: (NSArray *)types 5777- (BOOL) writeSelectionToPasteboard: (NSPasteboard *)pb types: (NSArray *)types
5767{ 5778{
5768 /* supposed to write for as many of types as we are able */ 5779 NSArray *typesDeclared;
5769 return NO; 5780 Lisp_Object val;
5781
5782 /* We only support NSStringPboardType */
5783 if ([types containsObject:NSStringPboardType] == NO) {
5784 return NO;
5785 }
5786
5787 val = ns_get_local_selection (QPRIMARY, QUTF8_STRING);
5788 if (CONSP (val) && SYMBOLP (XCAR (val)))
5789 {
5790 val = XCDR (val);
5791 if (CONSP (val) && NILP (XCDR (val)))
5792 val = XCAR (val);
5793 }
5794 if (! STRINGP (val))
5795 return NO;
5796
5797 typesDeclared = [NSArray arrayWithObject:NSStringPboardType];
5798 [pb declareTypes:typesDeclared owner:nil];
5799 ns_string_to_pasteboard (pb, val);
5800 return YES;
5770} 5801}
5771 5802
5772 5803
@@ -6038,14 +6069,26 @@ ns_term_shutdown (int sig)
6038 em_whole = whole; 6069 em_whole = whole;
6039 6070
6040 if (portion >= whole) 6071 if (portion >= whole)
6041 [self setFloatValue: 0.0 knobProportion: 1.0]; 6072 {
6073#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
6074 [self setKnobProportion: 1.0];
6075 [self setDoubleValue: 1.0];
6076#else
6077 [self setFloatValue: 0.0 knobProportion: 1.0];
6078#endif
6079 }
6042 else 6080 else
6043 { 6081 {
6044 float pos, por; 6082 float pos, por;
6045 portion = max ((float)whole*min_portion/pixel_height, portion); 6083 portion = max ((float)whole*min_portion/pixel_height, portion);
6046 pos = (float)position / (whole - portion); 6084 pos = (float)position / (whole - portion);
6047 por = (float)portion/whole; 6085 por = (float)portion/whole;
6086#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
6087 [self setKnobProportion: por];
6088 [self setDoubleValue: pos];
6089#else
6048 [self setFloatValue: pos knobProportion: por]; 6090 [self setFloatValue: pos knobProportion: por];
6091#endif
6049 } 6092 }
6050 return self; 6093 return self;
6051} 6094}
@@ -6390,6 +6433,8 @@ syms_of_nsterm (void)
6390 DEFSYM (Qsuper, "super"); 6433 DEFSYM (Qsuper, "super");
6391 DEFSYM (Qcontrol, "control"); 6434 DEFSYM (Qcontrol, "control");
6392 DEFSYM (Qnone, "none"); 6435 DEFSYM (Qnone, "none");
6436 DEFSYM (QUTF8_STRING, "UTF8_STRING");
6437
6393 Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); 6438 Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
6394 Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); 6439 Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier));
6395 Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); 6440 Fput (Qmeta, Qmodifier_value, make_number (meta_modifier));
diff --git a/src/process.c b/src/process.c
index 0fe7068af3b..1a884357b86 100644
--- a/src/process.c
+++ b/src/process.c
@@ -102,9 +102,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
102#include "gnutls.h" 102#include "gnutls.h"
103#endif 103#endif
104 104
105#if defined (USE_GTK) || defined (HAVE_GCONF) 105#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
106#include "xgselect.h" 106#include "xgselect.h"
107#endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ 107#endif
108#ifdef HAVE_NS 108#ifdef HAVE_NS
109#include "nsterm.h" 109#include "nsterm.h"
110#endif 110#endif
@@ -1652,7 +1652,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1652 sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); 1652 sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action );
1653#endif 1653#endif
1654#endif /* HAVE_WORKING_VFORK */ 1654#endif /* HAVE_WORKING_VFORK */
1655 sigprocmask (SIG_BLOCK, &blocked, &procmask); 1655 pthread_sigmask (SIG_BLOCK, &blocked, &procmask);
1656 1656
1657 FD_SET (inchannel, &input_wait_mask); 1657 FD_SET (inchannel, &input_wait_mask);
1658 FD_SET (inchannel, &non_keyboard_wait_mask); 1658 FD_SET (inchannel, &non_keyboard_wait_mask);
@@ -1808,7 +1808,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1808 signal (SIGPIPE, SIG_DFL); 1808 signal (SIGPIPE, SIG_DFL);
1809 1809
1810 /* Stop blocking signals in the child. */ 1810 /* Stop blocking signals in the child. */
1811 sigprocmask (SIG_SETMASK, &procmask, 0); 1811 pthread_sigmask (SIG_SETMASK, &procmask, 0);
1812 1812
1813 if (pty_flag) 1813 if (pty_flag)
1814 child_setup_tty (xforkout); 1814 child_setup_tty (xforkout);
@@ -1900,7 +1900,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1900#endif 1900#endif
1901#endif /* HAVE_WORKING_VFORK */ 1901#endif /* HAVE_WORKING_VFORK */
1902 /* Stop blocking signals in the parent. */ 1902 /* Stop blocking signals in the parent. */
1903 sigprocmask (SIG_SETMASK, &procmask, 0); 1903 pthread_sigmask (SIG_SETMASK, &procmask, 0);
1904 1904
1905 /* Now generate the error if vfork failed. */ 1905 /* Now generate the error if vfork failed. */
1906 if (pid < 0) 1906 if (pid < 0)
@@ -4527,7 +4527,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
4527 process_output_skip = 0; 4527 process_output_skip = 0;
4528 } 4528 }
4529#endif 4529#endif
4530#if defined (USE_GTK) || defined (HAVE_GCONF) 4530#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
4531 nfds = xg_select 4531 nfds = xg_select
4532#elif defined (HAVE_NS) 4532#elif defined (HAVE_NS)
4533 nfds = ns_select 4533 nfds = ns_select
diff --git a/src/ralloc.c b/src/ralloc.c
index 9c601a0ac24..64a47416202 100644
--- a/src/ralloc.c
+++ b/src/ralloc.c
@@ -1079,7 +1079,7 @@ r_alloc_reinit (void)
1079#include <assert.h> 1079#include <assert.h>
1080 1080
1081void 1081void
1082r_alloc_check () 1082r_alloc_check (void)
1083{ 1083{
1084 int found = 0; 1084 int found = 0;
1085 heap_ptr h, ph = 0; 1085 heap_ptr h, ph = 0;
diff --git a/src/regex.c b/src/regex.c
index 479239897bc..625c59ccf0b 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -2202,10 +2202,9 @@ extend_range_table_work_area (struct range_table_work_area *work_area)
2202 Returns -1 if successful, REG_ESPACE if ran out of space. */ 2202 Returns -1 if successful, REG_ESPACE if ran out of space. */
2203 2203
2204static int 2204static int
2205set_image_of_range_1 (work_area, start, end, translate) 2205set_image_of_range_1 (struct range_table_work_area *work_area,
2206 RE_TRANSLATE_TYPE translate; 2206 re_wchar_t start, re_wchar_t end,
2207 struct range_table_work_area *work_area; 2207 RE_TRANSLATE_TYPE translate)
2208 re_wchar_t start, end;
2209{ 2208{
2210 /* `one_case' indicates a character, or a run of characters, 2209 /* `one_case' indicates a character, or a run of characters,
2211 each of which is an isolate (no case-equivalents). 2210 each of which is an isolate (no case-equivalents).
@@ -2355,10 +2354,9 @@ set_image_of_range_1 (work_area, start, end, translate)
2355 Returns -1 if successful, REG_ESPACE if ran out of space. */ 2354 Returns -1 if successful, REG_ESPACE if ran out of space. */
2356 2355
2357static int 2356static int
2358set_image_of_range (work_area, start, end, translate) 2357set_image_of_range (struct range_table_work_area *work_area,
2359 RE_TRANSLATE_TYPE translate; 2358 re_wchar_t start, re_wchar_t end,
2360 struct range_table_work_area *work_area; 2359 RE_TRANSLATE_TYPE translate)
2361 re_wchar_t start, end;
2362{ 2360{
2363 re_wchar_t cmin, cmax; 2361 re_wchar_t cmin, cmax;
2364 2362
@@ -2445,8 +2443,7 @@ static re_char **best_regstart, **best_regend;
2445 but don't make them smaller. */ 2443 but don't make them smaller. */
2446 2444
2447static 2445static
2448regex_grow_registers (num_regs) 2446regex_grow_registers (int num_regs)
2449 int num_regs;
2450{ 2447{
2451 if (num_regs > regs_allocated_size) 2448 if (num_regs > regs_allocated_size)
2452 { 2449 {
diff --git a/src/s/irix6-5.h b/src/s/irix6-5.h
index d283571d8fb..26eb7dcde77 100644
--- a/src/s/irix6-5.h
+++ b/src/s/irix6-5.h
@@ -96,3 +96,10 @@ char *_getpty();
96/* Tested on Irix 6.5. SCM worked on earlier versions. */ 96/* Tested on Irix 6.5. SCM worked on earlier versions. */
97#define GC_SETJMP_WORKS 1 97#define GC_SETJMP_WORKS 1
98#define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS 98#define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS
99
100
101/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which
102 were stored in a Lisp_Object (as Emacs uses fewer than 32 bits for
103 the value field of a LISP_OBJECT). */
104#define DATA_START 0x10000000
105#define DATA_SEG_BITS 0x10000000
diff --git a/src/search.c b/src/search.c
index d29a51c695b..a56df784cd2 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2284,6 +2284,10 @@ The match found must start at or after that position.
2284Optional third argument, if t, means if fail just return nil (no error). 2284Optional third argument, if t, means if fail just return nil (no error).
2285 If not nil and not t, move to limit of search and return nil. 2285 If not nil and not t, move to limit of search and return nil.
2286Optional fourth argument is repeat count--search for successive occurrences. 2286Optional fourth argument is repeat count--search for successive occurrences.
2287
2288Search case-sensitivity is determined by the value of the variable
2289`case-fold-search', which see.
2290
2287See also the functions `match-beginning', `match-end', `match-string', 2291See also the functions `match-beginning', `match-end', `match-string',
2288and `replace-match'. */) 2292and `replace-match'. */)
2289 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) 2293 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
@@ -2300,6 +2304,10 @@ The match found must not extend after that position.
2300Optional third argument, if t, means if fail just return nil (no error). 2304Optional third argument, if t, means if fail just return nil (no error).
2301 If not nil and not t, move to limit of search and return nil. 2305 If not nil and not t, move to limit of search and return nil.
2302Optional fourth argument is repeat count--search for successive occurrences. 2306Optional fourth argument is repeat count--search for successive occurrences.
2307
2308Search case-sensitivity is determined by the value of the variable
2309`case-fold-search', which see.
2310
2303See also the functions `match-beginning', `match-end', `match-string', 2311See also the functions `match-beginning', `match-end', `match-string',
2304and `replace-match'. */) 2312and `replace-match'. */)
2305 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) 2313 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
@@ -2319,6 +2327,10 @@ The match found must start at or after that position.
2319Optional third argument, if t, means if fail just return nil (no error). 2327Optional third argument, if t, means if fail just return nil (no error).
2320 If not nil and not t, move to limit of search and return nil. 2328 If not nil and not t, move to limit of search and return nil.
2321Optional fourth argument is repeat count--search for successive occurrences. 2329Optional fourth argument is repeat count--search for successive occurrences.
2330
2331Search case-sensitivity is determined by the value of the variable
2332`case-fold-search', which see.
2333
2322See also the functions `match-beginning', `match-end', `match-string', 2334See also the functions `match-beginning', `match-end', `match-string',
2323and `replace-match'. */) 2335and `replace-match'. */)
2324 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) 2336 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
@@ -2336,6 +2348,10 @@ The match found must not extend after that position.
2336Optional third argument, if t, means if fail just return nil (no error). 2348Optional third argument, if t, means if fail just return nil (no error).
2337 If not nil and not t, move to limit of search and return nil. 2349 If not nil and not t, move to limit of search and return nil.
2338Optional fourth argument is repeat count--search for successive occurrences. 2350Optional fourth argument is repeat count--search for successive occurrences.
2351
2352Search case-sensitivity is determined by the value of the variable
2353`case-fold-search', which see.
2354
2339See also the functions `match-beginning', `match-end', `match-string', 2355See also the functions `match-beginning', `match-end', `match-string',
2340and `replace-match'. */) 2356and `replace-match'. */)
2341 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count) 2357 (Lisp_Object regexp, Lisp_Object bound, Lisp_Object noerror, Lisp_Object count)
diff --git a/src/sysdep.c b/src/sysdep.c
index 3a73b1a467b..fc2f846b0dc 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1534,7 +1534,7 @@ sigset_t
1534sys_sigblock (sigset_t new_mask) 1534sys_sigblock (sigset_t new_mask)
1535{ 1535{
1536 sigset_t old_mask; 1536 sigset_t old_mask;
1537 sigprocmask (SIG_BLOCK, &new_mask, &old_mask); 1537 pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask);
1538 return (old_mask); 1538 return (old_mask);
1539} 1539}
1540 1540
@@ -1542,7 +1542,7 @@ sigset_t
1542sys_sigunblock (sigset_t new_mask) 1542sys_sigunblock (sigset_t new_mask)
1543{ 1543{
1544 sigset_t old_mask; 1544 sigset_t old_mask;
1545 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask); 1545 pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask);
1546 return (old_mask); 1546 return (old_mask);
1547} 1547}
1548 1548
@@ -1550,7 +1550,7 @@ sigset_t
1550sys_sigsetmask (sigset_t new_mask) 1550sys_sigsetmask (sigset_t new_mask)
1551{ 1551{
1552 sigset_t old_mask; 1552 sigset_t old_mask;
1553 sigprocmask (SIG_SETMASK, &new_mask, &old_mask); 1553 pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask);
1554 return (old_mask); 1554 return (old_mask);
1555} 1555}
1556 1556
@@ -1783,7 +1783,8 @@ seed_random (long int arg)
1783} 1783}
1784 1784
1785/* 1785/*
1786 * Build a full Emacs-sized word out of whatever we've got. 1786 * Return a nonnegative random integer out of whatever we've got.
1787 * It contains enough bits to make a random (signed) Emacs fixnum.
1787 * This suffices even for a 64-bit architecture with a 15-bit rand. 1788 * This suffices even for a 64-bit architecture with a 15-bit rand.
1788 */ 1789 */
1789EMACS_INT 1790EMACS_INT
@@ -1791,16 +1792,17 @@ get_random (void)
1791{ 1792{
1792 EMACS_UINT val = 0; 1793 EMACS_UINT val = 0;
1793 int i; 1794 int i;
1794 for (i = 0; i < (VALBITS + RAND_BITS - 1) / RAND_BITS; i++) 1795 for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++)
1795 val = (val << RAND_BITS) ^ random (); 1796 val = (random () ^ (val << RAND_BITS)
1796 return val & (((EMACS_INT) 1 << VALBITS) - 1); 1797 ^ (val >> (BITS_PER_EMACS_INT - RAND_BITS)));
1798 val ^= val >> (BITS_PER_EMACS_INT - FIXNUM_BITS);
1799 return val & INTMASK;
1797} 1800}
1798 1801
1799#ifndef HAVE_STRERROR 1802#ifndef HAVE_STRERROR
1800#ifndef WINDOWSNT 1803#ifndef WINDOWSNT
1801char * 1804char *
1802strerror (errnum) 1805strerror (int errnum)
1803 int errnum;
1804{ 1806{
1805 extern char *sys_errlist[]; 1807 extern char *sys_errlist[];
1806 extern int sys_nerr; 1808 extern int sys_nerr;
diff --git a/src/term.c b/src/term.c
index 9205719b5f4..22056451cb9 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1546,7 +1546,8 @@ produce_glyphs (struct it *it)
1546 /* Nothing but characters are supported on terminal frames. */ 1546 /* Nothing but characters are supported on terminal frames. */
1547 xassert (it->what == IT_CHARACTER 1547 xassert (it->what == IT_CHARACTER
1548 || it->what == IT_COMPOSITION 1548 || it->what == IT_COMPOSITION
1549 || it->what == IT_STRETCH); 1549 || it->what == IT_STRETCH
1550 || it->what == IT_GLYPHLESS);
1550 1551
1551 if (it->what == IT_STRETCH) 1552 if (it->what == IT_STRETCH)
1552 { 1553 {
@@ -3096,7 +3097,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3096 char *area = NULL; 3097 char *area = NULL;
3097 char **address = &area; 3098 char **address = &area;
3098 int buffer_size = 4096; 3099 int buffer_size = 4096;
3099 register char *p = NULL;
3100 int status; 3100 int status;
3101 struct tty_display_info *tty = NULL; 3101 struct tty_display_info *tty = NULL;
3102 struct terminal *terminal = NULL; 3102 struct terminal *terminal = NULL;
@@ -3504,55 +3504,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3504 Down (tty) = 0; 3504 Down (tty) = 0;
3505 } 3505 }
3506 3506
3507 /* Special handling for certain terminal types known to need it */
3508
3509 if (!strcmp (terminal_type, "supdup"))
3510 {
3511 terminal->memory_below_frame = 1;
3512 tty->Wcm->cm_losewrap = 1;
3513 }
3514 if (!strncmp (terminal_type, "c10", 3)
3515 || !strcmp (terminal_type, "perq"))
3516 {
3517 /* Supply a makeshift :wi string.
3518 This string is not valid in general since it works only
3519 for windows starting at the upper left corner;
3520 but that is all Emacs uses.
3521
3522 This string works only if the frame is using
3523 the top of the video memory, because addressing is memory-relative.
3524 So first check the :ti string to see if that is true.
3525
3526 It would be simpler if the :wi string could go in the termcap
3527 entry, but it can't because it is not fully valid.
3528 If it were in the termcap entry, it would confuse other programs. */
3529 if (!tty->TS_set_window)
3530 {
3531 const char *m = tty->TS_termcap_modes;
3532 while (*m && strcmp (m, "\033v "))
3533 m++;
3534 if (*m)
3535 tty->TS_set_window = "\033v%C %C %C %C ";
3536 }
3537 /* Termcap entry often fails to have :in: flag */
3538 terminal->must_write_spaces = 1;
3539 /* :ti string typically fails to have \E^G! in it */
3540 /* This limits scope of insert-char to one line. */
3541 strcpy (area, tty->TS_termcap_modes);
3542 strcat (area, "\033\007!");
3543 tty->TS_termcap_modes = area;
3544 area += strlen (area) + 1;
3545 p = AbsPosition (tty);
3546 /* Change all %+ parameters to %C, to handle
3547 values above 96 correctly for the C100. */
3548 while (*p)
3549 {
3550 if (p[0] == '%' && p[1] == '+')
3551 p[1] = 'C';
3552 p++;
3553 }
3554 }
3555
3556 tty->specified_window = FrameRows (tty); 3507 tty->specified_window = FrameRows (tty);
3557 3508
3558 if (Wcm_init (tty) == -1) /* can't do cursor motion */ 3509 if (Wcm_init (tty) == -1) /* can't do cursor motion */
diff --git a/src/termcap.c b/src/termcap.c
index e191f6b3af3..96b9303d62d 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -338,8 +338,7 @@ static int name_match (char *line, char *name);
338 338
339#ifdef MSDOS /* MW, May 1993 */ 339#ifdef MSDOS /* MW, May 1993 */
340static int 340static int
341valid_filename_p (fn) 341valid_filename_p (char *fn)
342 char *fn;
343{ 342{
344 return *fn == '/' || fn[1] == ':'; 343 return *fn == '/' || fn[1] == ':';
345} 344}
@@ -669,9 +668,29 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
669 668
670#include <stdio.h> 669#include <stdio.h>
671 670
672main (argc, argv) 671static void
673 int argc; 672tprint (char *cap)
674 char **argv; 673{
674 char *x = tgetstr (cap, 0);
675 register char *y;
676
677 printf ("%s: ", cap);
678 if (x)
679 {
680 for (y = x; *y; y++)
681 if (*y <= ' ' || *y == 0177)
682 printf ("\\%0o", *y);
683 else
684 putchar (*y);
685 free (x);
686 }
687 else
688 printf ("none");
689 putchar ('\n');
690}
691
692int
693main (int argc, char **argv)
675{ 694{
676 char *term; 695 char *term;
677 char *buf; 696 char *buf;
@@ -693,27 +712,8 @@ main (argc, argv)
693 712
694 printf ("co: %d\n", tgetnum ("co")); 713 printf ("co: %d\n", tgetnum ("co"));
695 printf ("am: %d\n", tgetflag ("am")); 714 printf ("am: %d\n", tgetflag ("am"));
696}
697
698tprint (cap)
699 char *cap;
700{
701 char *x = tgetstr (cap, 0);
702 register char *y;
703 715
704 printf ("%s: ", cap); 716 return 0;
705 if (x)
706 {
707 for (y = x; *y; y++)
708 if (*y <= ' ' || *y == 0177)
709 printf ("\\%0o", *y);
710 else
711 putchar (*y);
712 free (x);
713 }
714 else
715 printf ("none");
716 putchar ('\n');
717} 717}
718 718
719#endif /* TEST */ 719#endif /* TEST */
diff --git a/src/textprop.c b/src/textprop.c
index 87f1675047b..29425f7a550 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -1707,10 +1707,14 @@ text_property_stickiness (Lisp_Object prop, Lisp_Object pos, Lisp_Object buffer)
1707{ 1707{
1708 Lisp_Object prev_pos, front_sticky; 1708 Lisp_Object prev_pos, front_sticky;
1709 int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */ 1709 int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */
1710 Lisp_Object defalt = Fassq (prop, Vtext_property_default_nonsticky);
1710 1711
1711 if (NILP (buffer)) 1712 if (NILP (buffer))
1712 XSETBUFFER (buffer, current_buffer); 1713 XSETBUFFER (buffer, current_buffer);
1713 1714
1715 if (CONSP (defalt) && !NILP (XCDR (defalt)))
1716 is_rear_sticky = 0;
1717
1714 if (XINT (pos) > BUF_BEGV (XBUFFER (buffer))) 1718 if (XINT (pos) > BUF_BEGV (XBUFFER (buffer)))
1715 /* Consider previous character. */ 1719 /* Consider previous character. */
1716 { 1720 {
@@ -2230,9 +2234,11 @@ If a character in a buffer has PROPERTY, new text inserted adjacent to
2230the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil, 2234the character doesn't inherit PROPERTY if NONSTICKINESS is non-nil,
2231inherits it if NONSTICKINESS is nil. The `front-sticky' and 2235inherits it if NONSTICKINESS is nil. The `front-sticky' and
2232`rear-nonsticky' properties of the character override NONSTICKINESS. */); 2236`rear-nonsticky' properties of the character override NONSTICKINESS. */);
2233 /* Text property `syntax-table' should be nonsticky by default. */ 2237 /* Text properties `syntax-table'and `display' should be nonsticky
2238 by default. */
2234 Vtext_property_default_nonsticky 2239 Vtext_property_default_nonsticky
2235 = Fcons (Fcons (intern_c_string ("syntax-table"), Qt), Qnil); 2240 = Fcons (Fcons (intern_c_string ("syntax-table"), Qt),
2241 Fcons (Fcons (intern_c_string ("display"), Qt), Qnil));
2236 2242
2237 staticpro (&interval_insert_behind_hooks); 2243 staticpro (&interval_insert_behind_hooks);
2238 staticpro (&interval_insert_in_front_hooks); 2244 staticpro (&interval_insert_in_front_hooks);
diff --git a/src/tparam.c b/src/tparam.c
index 6aae0b97db9..ed28cd7397f 100644
--- a/src/tparam.c
+++ b/src/tparam.c
@@ -265,9 +265,8 @@ tparam1 (const char *string, char *outstring, int len,
265 265
266#ifdef DEBUG 266#ifdef DEBUG
267 267
268main (argc, argv) 268int
269 int argc; 269main (int argc, char **argv)
270 char **argv;
271{ 270{
272 char buf[50]; 271 char buf[50];
273 int args[3]; 272 int args[3];
diff --git a/src/unexhp9k800.c b/src/unexhp9k800.c
index f27415a252c..ce65faffd4e 100644
--- a/src/unexhp9k800.c
+++ b/src/unexhp9k800.c
@@ -64,8 +64,7 @@ static long brk_on_dump = 0;
64 64
65/* Called from main, if we use shared libraries. */ 65/* Called from main, if we use shared libraries. */
66int 66int
67run_time_remap (ignored) 67run_time_remap (char *ignored)
68 char *ignored;
69{ 68{
70 brk ((char *) brk_on_dump); 69 brk ((char *) brk_on_dump);
71} 70}
@@ -74,74 +73,11 @@ run_time_remap (ignored)
74#define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1)) /* n is power of 2 */ 73#define roundup(x,n) (((x) + ((n) - 1)) & ~((n) - 1)) /* n is power of 2 */
75#define min(x,y) (((x) < (y)) ? (x) : (y)) 74#define min(x,y) (((x) < (y)) ? (x) : (y))
76 75
77
78/* Create a new a.out file, same as old but with current data space */
79void
80unexec (const char *new_name, /* name of the new a.out file to be created */
81 const char *old_name) /* name of the old a.out file */
82{
83 int old, new;
84 int old_size, new_size;
85 struct header hdr;
86 struct som_exec_auxhdr auxhdr;
87 long i;
88
89 /* For the greatest flexibility, should create a temporary file in
90 the same directory as the new file. When everything is complete,
91 rename the temp file to the new name.
92 This way, a program could update its own a.out file even while
93 it is still executing. If problems occur, everything is still
94 intact. NOT implemented. */
95
96 /* Open the input and output a.out files */
97 old = open (old_name, O_RDONLY);
98 if (old < 0)
99 { perror (old_name); exit (1); }
100 new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777);
101 if (new < 0)
102 { perror (new_name); exit (1); }
103
104 /* Read the old headers */
105 read_header (old, &hdr, &auxhdr);
106
107 brk_on_dump = (long) sbrk (0);
108
109 /* Decide how large the new and old data areas are */
110 old_size = auxhdr.exec_dsize;
111 /* I suspect these two statements are separate
112 to avoid a compiler bug in hpux version 8. */
113 i = (long) sbrk (0);
114 new_size = i - auxhdr.exec_dmem;
115
116 /* Copy the old file to the new, up to the data space */
117 lseek (old, 0, 0);
118 copy_file (old, new, auxhdr.exec_dfile);
119
120 /* Skip the old data segment and write a new one */
121 lseek (old, old_size, 1);
122 save_data_space (new, &hdr, &auxhdr, new_size);
123
124 /* Copy the rest of the file */
125 copy_rest (old, new);
126
127 /* Update file pointers since we probably changed size of data area */
128 update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size);
129
130 /* Save the modified header */
131 write_header (new, &hdr, &auxhdr);
132
133 /* Close the binary file */
134 close (old);
135 close (new);
136}
137
138/* Save current data space in the file, update header. */ 76/* Save current data space in the file, update header. */
139 77
140save_data_space (file, hdr, auxhdr, size) 78static void
141 int file; 79save_data_space (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr,
142 struct header *hdr; 80 int size)
143 struct som_exec_auxhdr *auxhdr;
144 int size;
145{ 81{
146 /* Write the entire data space out to the file */ 82 /* Write the entire data space out to the file */
147 if (write (file, auxhdr->exec_dmem, size) != size) 83 if (write (file, auxhdr->exec_dmem, size) != size)
@@ -154,12 +90,9 @@ save_data_space (file, hdr, auxhdr, size)
154 90
155/* Update the values of file pointers when something is inserted. */ 91/* Update the values of file pointers when something is inserted. */
156 92
157update_file_ptrs (file, hdr, auxhdr, location, offset) 93static void
158 int file; 94update_file_ptrs (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr,
159 struct header *hdr; 95 unsigned int location, int offset)
160 struct som_exec_auxhdr *auxhdr;
161 unsigned int location;
162 int offset;
163{ 96{
164 struct subspace_dictionary_record subspace; 97 struct subspace_dictionary_record subspace;
165 int i; 98 int i;
@@ -205,10 +138,8 @@ update_file_ptrs (file, hdr, auxhdr, location, offset)
205 138
206/* Read in the header records from an a.out file. */ 139/* Read in the header records from an a.out file. */
207 140
208read_header (file, hdr, auxhdr) 141static void
209 int file; 142read_header (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr)
210 struct header *hdr;
211 struct som_exec_auxhdr *auxhdr;
212{ 143{
213 144
214 /* Read the header in */ 145 /* Read the header in */
@@ -233,10 +164,8 @@ read_header (file, hdr, auxhdr)
233 164
234/* Write out the header records into an a.out file. */ 165/* Write out the header records into an a.out file. */
235 166
236write_header (file, hdr, auxhdr) 167static void
237 int file; 168write_header (int file, struct header *hdr, struct som_exec_auxhdr *auxhdr)
238 struct header *hdr;
239 struct som_exec_auxhdr *auxhdr;
240{ 169{
241 /* Update the checksum */ 170 /* Update the checksum */
242 hdr->checksum = calculate_checksum (hdr); 171 hdr->checksum = calculate_checksum (hdr);
@@ -252,8 +181,8 @@ write_header (file, hdr, auxhdr)
252 181
253/* Calculate the checksum of a SOM header record. */ 182/* Calculate the checksum of a SOM header record. */
254 183
255calculate_checksum (hdr) 184static int
256 struct header *hdr; 185calculate_checksum (struct header *hdr)
257{ 186{
258 int checksum, i, *ptr; 187 int checksum, i, *ptr;
259 188
@@ -267,9 +196,8 @@ calculate_checksum (hdr)
267 196
268/* Copy size bytes from the old file to the new one. */ 197/* Copy size bytes from the old file to the new one. */
269 198
270copy_file (old, new, size) 199static void
271 int new, old; 200copy_file (int old, int new, int size)
272 int size;
273{ 201{
274 int len; 202 int len;
275 int buffer[8192]; /* word aligned will be faster */ 203 int buffer[8192]; /* word aligned will be faster */
@@ -286,8 +214,8 @@ copy_file (old, new, size)
286 214
287/* Copy the rest of the file, up to EOF. */ 215/* Copy the rest of the file, up to EOF. */
288 216
289copy_rest (old, new) 217static void
290 int new, old; 218copy_rest (int old, int new)
291{ 219{
292 int buffer[4096]; 220 int buffer[4096];
293 int len; 221 int len;
@@ -301,9 +229,8 @@ copy_rest (old, new)
301} 229}
302 230
303#ifdef DEBUG 231#ifdef DEBUG
304display_header (hdr, auxhdr) 232static void
305 struct header *hdr; 233display_header (struct header *hdr, struct som_exec_auxhdr *auxhdr)
306 struct som_exec_auxhdr *auxhdr;
307{ 234{
308 /* Display the header information (debug) */ 235 /* Display the header information (debug) */
309 printf ("\n\nFILE HEADER\n"); 236 printf ("\n\nFILE HEADER\n");
@@ -320,3 +247,64 @@ display_header (hdr, auxhdr)
320 hdr->unloadable_sp_location, hdr->unloadable_sp_size); 247 hdr->unloadable_sp_location, hdr->unloadable_sp_size);
321} 248}
322#endif /* DEBUG */ 249#endif /* DEBUG */
250
251
252/* Create a new a.out file, same as old but with current data space */
253void
254unexec (const char *new_name, /* name of the new a.out file to be created */
255 const char *old_name) /* name of the old a.out file */
256{
257 int old, new;
258 int old_size, new_size;
259 struct header hdr;
260 struct som_exec_auxhdr auxhdr;
261 long i;
262
263 /* For the greatest flexibility, should create a temporary file in
264 the same directory as the new file. When everything is complete,
265 rename the temp file to the new name.
266 This way, a program could update its own a.out file even while
267 it is still executing. If problems occur, everything is still
268 intact. NOT implemented. */
269
270 /* Open the input and output a.out files */
271 old = open (old_name, O_RDONLY);
272 if (old < 0)
273 { perror (old_name); exit (1); }
274 new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777);
275 if (new < 0)
276 { perror (new_name); exit (1); }
277
278 /* Read the old headers */
279 read_header (old, &hdr, &auxhdr);
280
281 brk_on_dump = (long) sbrk (0);
282
283 /* Decide how large the new and old data areas are */
284 old_size = auxhdr.exec_dsize;
285 /* I suspect these two statements are separate
286 to avoid a compiler bug in hpux version 8. */
287 i = (long) sbrk (0);
288 new_size = i - auxhdr.exec_dmem;
289
290 /* Copy the old file to the new, up to the data space */
291 lseek (old, 0, 0);
292 copy_file (old, new, auxhdr.exec_dfile);
293
294 /* Skip the old data segment and write a new one */
295 lseek (old, old_size, 1);
296 save_data_space (new, &hdr, &auxhdr, new_size);
297
298 /* Copy the rest of the file */
299 copy_rest (old, new);
300
301 /* Update file pointers since we probably changed size of data area */
302 update_file_ptrs (new, &hdr, &auxhdr, auxhdr.exec_dfile, new_size-old_size);
303
304 /* Save the modified header */
305 write_header (new, &hdr, &auxhdr);
306
307 /* Close the binary file */
308 close (old);
309 close (new);
310}
diff --git a/src/w32.c b/src/w32.c
index 53bf2e811e2..de72e180c62 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1452,6 +1452,14 @@ sigprocmask (int how, const sigset_t *set, sigset_t *oset)
1452} 1452}
1453 1453
1454int 1454int
1455pthread_sigmask (int how, const sigset_t *set, sigset_t *oset)
1456{
1457 if (sigprocmask (how, set, oset) == -1)
1458 return EINVAL;
1459 return 0;
1460}
1461
1462int
1455setpgrp (int pid, int gid) 1463setpgrp (int pid, int gid)
1456{ 1464{
1457 return 0; 1465 return 0;
diff --git a/src/w32fns.c b/src/w32fns.c
index e4b11b70441..f48e5764b4c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -3273,7 +3273,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3273 { 3273 {
3274 /* Free memory used by owner-drawn and help-echo strings. */ 3274 /* Free memory used by owner-drawn and help-echo strings. */
3275 w32_free_menu_strings (hwnd); 3275 w32_free_menu_strings (hwnd);
3276 f->output_data.w32->menubar_active = 0; 3276 if (f)
3277 f->output_data.w32->menubar_active = 0;
3277 menubar_in_use = 0; 3278 menubar_in_use = 0;
3278 } 3279 }
3279 } 3280 }
@@ -3623,10 +3624,10 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3623 if (LOWORD (lParam) == HTCLIENT) 3624 if (LOWORD (lParam) == HTCLIENT)
3624 { 3625 {
3625 f = x_window_to_frame (dpyinfo, hwnd); 3626 f = x_window_to_frame (dpyinfo, hwnd);
3626 if (f->output_data.w32->hourglass_p && !menubar_in_use 3627 if (f && f->output_data.w32->hourglass_p
3627 && !current_popup_menu) 3628 && !menubar_in_use && !current_popup_menu)
3628 SetCursor (f->output_data.w32->hourglass_cursor); 3629 SetCursor (f->output_data.w32->hourglass_cursor);
3629 else 3630 else if (f)
3630 SetCursor (f->output_data.w32->current_cursor); 3631 SetCursor (f->output_data.w32->current_cursor);
3631 return 0; 3632 return 0;
3632 } 3633 }
@@ -6805,10 +6806,6 @@ syms_of_w32fns (void)
6805 DEFSYM (Qfont_param, "font-parameter"); 6806 DEFSYM (Qfont_param, "font-parameter");
6806 /* This is the end of symbol initialization. */ 6807 /* This is the end of symbol initialization. */
6807 6808
6808 /* Text property `display' should be nonsticky by default. */
6809 Vtext_property_default_nonsticky
6810 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
6811
6812 6809
6813 Fput (Qundefined_color, Qerror_conditions, 6810 Fput (Qundefined_color, Qerror_conditions,
6814 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); 6811 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
diff --git a/src/widget.c b/src/widget.c
index 6d871ad7cb2..a09ec2631ad 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -224,8 +224,7 @@ get_wm_shell (Widget w)
224#if 0 /* Currently not used. */ 224#if 0 /* Currently not used. */
225 225
226static void 226static void
227mark_shell_size_user_specified (wmshell) 227mark_shell_size_user_specified (Widget wmshell)
228 Widget wmshell;
229{ 228{
230 if (! XtIsWMShell (wmshell)) abort (); 229 if (! XtIsWMShell (wmshell)) abort ();
231 /* This is kind of sleazy, but I can't see how else to tell it to make it 230 /* This is kind of sleazy, but I can't see how else to tell it to make it
@@ -510,8 +509,7 @@ update_wm_hints (EmacsFrame ew)
510#if 0 509#if 0
511 510
512static void 511static void
513create_frame_gcs (ew) 512create_frame_gcs (EmacsFrame ew)
514 EmacsFrame ew;
515{ 513{
516 struct frame *s = ew->emacs_frame.frame; 514 struct frame *s = ew->emacs_frame.frame;
517 515
diff --git a/src/window.c b/src/window.c
index 3c867145620..d39efa8071d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -56,7 +56,7 @@ Lisp_Object Qwindowp, Qwindow_live_p;
56static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; 56static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
57static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 57static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
58static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 58static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
59static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; 59static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
60static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 60static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
61static Lisp_Object Qsafe, Qabove, Qbelow; 61static Lisp_Object Qsafe, Qabove, Qbelow;
62static Lisp_Object Qauto_buffer_name; 62static Lisp_Object Qauto_buffer_name;
@@ -410,14 +410,6 @@ buffer of the selected window before each command. */)
410 return select_window (window, norecord, 0); 410 return select_window (window, norecord, 0);
411} 411}
412 412
413DEFUN ("window-clone-number", Fwindow_clone_number, Swindow_clone_number, 0, 1, 0,
414 doc: /* Return WINDOW's clone number.
415WINDOW can be any window and defaults to the selected one. */)
416 (Lisp_Object window)
417{
418 return decode_any_window (window)->clone_number;
419}
420
421DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0, 413DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
422 doc: /* Return the buffer that WINDOW is displaying. 414 doc: /* Return the buffer that WINDOW is displaying.
423WINDOW can be any window and defaults to the selected one. 415WINDOW can be any window and defaults to the selected one.
@@ -693,6 +685,7 @@ WINDOW must be a live window and defaults to the selected one. */)
693 685
694DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, 686DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
695 doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL. 687 doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
688If WINDOW is nil, the selected window is used.
696Return NCOL. NCOL should be zero or positive. 689Return NCOL. NCOL should be zero or positive.
697 690
698Note that if `automatic-hscrolling' is non-nil, you cannot scroll the 691Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
@@ -1360,6 +1353,7 @@ if it isn't already recorded. */)
1360 struct text_pos startp; 1353 struct text_pos startp;
1361 struct it it; 1354 struct it it;
1362 struct buffer *old_buffer = NULL; 1355 struct buffer *old_buffer = NULL;
1356 void *itdata = NULL;
1363 1357
1364 /* Cannot use Fvertical_motion because that function doesn't 1358 /* Cannot use Fvertical_motion because that function doesn't
1365 cope with variable-height lines. */ 1359 cope with variable-height lines. */
@@ -1381,11 +1375,13 @@ if it isn't already recorded. */)
1381 else 1375 else
1382 SET_TEXT_POS_FROM_MARKER (startp, w->start); 1376 SET_TEXT_POS_FROM_MARKER (startp, w->start);
1383 1377
1378 itdata = bidi_shelve_cache ();
1384 start_display (&it, w, startp); 1379 start_display (&it, w, startp);
1385 move_it_vertically (&it, window_box_height (w)); 1380 move_it_vertically (&it, window_box_height (w));
1386 if (it.current_y < it.last_visible_y) 1381 if (it.current_y < it.last_visible_y)
1387 move_it_past_eol (&it); 1382 move_it_past_eol (&it);
1388 value = make_number (IT_CHARPOS (it)); 1383 value = make_number (IT_CHARPOS (it));
1384 bidi_unshelve_cache (itdata);
1389 1385
1390 if (old_buffer) 1386 if (old_buffer)
1391 set_buffer_internal (old_buffer); 1387 set_buffer_internal (old_buffer);
@@ -1420,7 +1416,7 @@ Return POS. */)
1420 1416
1421DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0, 1417DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
1422 doc: /* Make display in WINDOW start at position POS in WINDOW's buffer. 1418 doc: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1423WINDOW defaults to the selected window. Return POS. 1419If WINDOW is nil, the selected window is used. Return POS.
1424Optional third arg NOFORCE non-nil inhibits next redisplay from 1420Optional third arg NOFORCE non-nil inhibits next redisplay from
1425overriding motion of point in order to display at this exact start. */) 1421overriding motion of point in order to display at this exact start. */)
1426 (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce) 1422 (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce)
@@ -2578,7 +2574,7 @@ selected frame and no others. */)
2578static Lisp_Object 2574static Lisp_Object
2579resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) 2575resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
2580{ 2576{
2581 return call4 (Qresize_root_window, window, delta, horizontal, ignore); 2577 return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore);
2582} 2578}
2583 2579
2584 2580
@@ -3089,18 +3085,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3089 unbind_to (count, Qnil); 3085 unbind_to (count, Qnil);
3090} 3086}
3091 3087
3092DEFUN ("set-window-clone-number", Fset_window_clone_number, Sset_window_clone_number, 2, 2, 0,
3093 doc: /* Set WINDOW's clone number to CLONE-NUMBER.
3094WINDOW can be any window and defaults to the selected one. */)
3095 (Lisp_Object window, Lisp_Object clone_number)
3096{
3097 register struct window *w = decode_any_window (window);
3098
3099 CHECK_NUMBER (clone_number);
3100 w->clone_number = clone_number;
3101 return w->clone_number;
3102}
3103
3104DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, 3088DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
3105 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. 3089 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
3106WINDOW has to be a live window and defaults to the selected one. 3090WINDOW has to be a live window and defaults to the selected one.
@@ -3291,7 +3275,6 @@ make_parent_window (Lisp_Object window, int horflag)
3291 3275
3292 ++sequence_number; 3276 ++sequence_number;
3293 XSETFASTINT (p->sequence_number, sequence_number); 3277 XSETFASTINT (p->sequence_number, sequence_number);
3294 XSETFASTINT (p->clone_number, sequence_number);
3295 3278
3296 replace_window (window, parent, 1); 3279 replace_window (window, parent, 1);
3297 3280
@@ -3337,7 +3320,6 @@ make_window (void)
3337 XSETFASTINT (w->use_time, 0); 3320 XSETFASTINT (w->use_time, 0);
3338 ++sequence_number; 3321 ++sequence_number;
3339 XSETFASTINT (w->sequence_number, sequence_number); 3322 XSETFASTINT (w->sequence_number, sequence_number);
3340 XSETFASTINT (w->clone_number, sequence_number);
3341 w->temslot = w->last_modified = w->last_overlay_modified = Qnil; 3323 w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
3342 XSETFASTINT (w->last_point, 0); 3324 XSETFASTINT (w->last_point, 0);
3343 w->last_had_star = w->vertical_scroll_bar = Qnil; 3325 w->last_had_star = w->vertical_scroll_bar = Qnil;
@@ -4076,7 +4058,8 @@ grow_mini_window (struct window *w, int delta)
4076 4058
4077 root = FRAME_ROOT_WINDOW (f); 4059 root = FRAME_ROOT_WINDOW (f);
4078 r = XWINDOW (root); 4060 r = XWINDOW (root);
4079 value = call2 (Qresize_root_window_vertically, root, make_number (- delta)); 4061 value = call2 (Qwindow_resize_root_window_vertically,
4062 root, make_number (- delta));
4080 if (INTEGERP (value) && window_resize_check (r, 0)) 4063 if (INTEGERP (value) && window_resize_check (r, 0))
4081 { 4064 {
4082 BLOCK_INPUT; 4065 BLOCK_INPUT;
@@ -4110,7 +4093,7 @@ shrink_mini_window (struct window *w)
4110 { 4093 {
4111 root = FRAME_ROOT_WINDOW (f); 4094 root = FRAME_ROOT_WINDOW (f);
4112 r = XWINDOW (root); 4095 r = XWINDOW (root);
4113 value = call2 (Qresize_root_window_vertically, 4096 value = call2 (Qwindow_resize_root_window_vertically,
4114 root, make_number (size - 1)); 4097 root, make_number (size - 1));
4115 if (INTEGERP (value) && window_resize_check (r, 0)) 4098 if (INTEGERP (value) && window_resize_check (r, 0))
4116 { 4099 {
@@ -4261,6 +4244,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4261 /* True if we fiddled the window vscroll field without really scrolling. */ 4244 /* True if we fiddled the window vscroll field without really scrolling. */
4262 int vscrolled = 0; 4245 int vscrolled = 0;
4263 int x, y, rtop, rbot, rowh, vpos; 4246 int x, y, rtop, rbot, rowh, vpos;
4247 void *itdata = NULL;
4264 4248
4265 SET_TEXT_POS_FROM_MARKER (start, w->start); 4249 SET_TEXT_POS_FROM_MARKER (start, w->start);
4266 4250
@@ -4271,6 +4255,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4271 4255
4272 if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos)) 4256 if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
4273 { 4257 {
4258 itdata = bidi_shelve_cache ();
4274 /* Move backward half the height of the window. Performance note: 4259 /* Move backward half the height of the window. Performance note:
4275 vmotion used here is about 10% faster, but would give wrong 4260 vmotion used here is about 10% faster, but would give wrong
4276 results for variable height lines. */ 4261 results for variable height lines. */
@@ -4291,6 +4276,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4291 } 4276 }
4292 4277
4293 start = it.current.pos; 4278 start = it.current.pos;
4279 bidi_unshelve_cache (itdata);
4294 } 4280 }
4295 else if (auto_window_vscroll_p) 4281 else if (auto_window_vscroll_p)
4296 { 4282 {
@@ -4353,6 +4339,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4353 Fset_window_vscroll (window, make_number (0), Qt); 4339 Fset_window_vscroll (window, make_number (0), Qt);
4354 } 4340 }
4355 4341
4342 itdata = bidi_shelve_cache ();
4356 /* If scroll_preserve_screen_position is non-nil, we try to set 4343 /* If scroll_preserve_screen_position is non-nil, we try to set
4357 point in the same window line as it is now, so get that line. */ 4344 point in the same window line as it is now, so get that line. */
4358 if (!NILP (Vscroll_preserve_screen_position)) 4345 if (!NILP (Vscroll_preserve_screen_position))
@@ -4431,12 +4418,16 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4431 - it.current_y + it.max_ascent + it.max_descent); 4418 - it.current_y + it.max_ascent + it.max_descent);
4432 adjust_glyphs (it.f); 4419 adjust_glyphs (it.f);
4433 } 4420 }
4434 else if (noerror)
4435 return;
4436 else if (n < 0) /* could happen with empty buffers */
4437 xsignal0 (Qbeginning_of_buffer);
4438 else 4421 else
4439 xsignal0 (Qend_of_buffer); 4422 {
4423 bidi_unshelve_cache (itdata);
4424 if (noerror)
4425 return;
4426 else if (n < 0) /* could happen with empty buffers */
4427 xsignal0 (Qbeginning_of_buffer);
4428 else
4429 xsignal0 (Qend_of_buffer);
4430 }
4440 } 4431 }
4441 else 4432 else
4442 { 4433 {
@@ -4444,10 +4435,14 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4444 /* The first line was only partially visible, make it fully 4435 /* The first line was only partially visible, make it fully
4445 visible. */ 4436 visible. */
4446 w->vscroll = 0; 4437 w->vscroll = 0;
4447 else if (noerror)
4448 return;
4449 else 4438 else
4450 xsignal0 (Qbeginning_of_buffer); 4439 {
4440 bidi_unshelve_cache (itdata);
4441 if (noerror)
4442 return;
4443 else
4444 xsignal0 (Qbeginning_of_buffer);
4445 }
4451 } 4446 }
4452 4447
4453 /* If control gets here, then we vscrolled. */ 4448 /* If control gets here, then we vscrolled. */
@@ -4591,6 +4586,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4591 SET_PT_BOTH (charpos, bytepos); 4586 SET_PT_BOTH (charpos, bytepos);
4592 } 4587 }
4593 } 4588 }
4589 bidi_unshelve_cache (itdata);
4594} 4590}
4595 4591
4596 4592
@@ -4993,6 +4989,7 @@ displayed_window_lines (struct window *w)
4993 int height = window_box_height (w); 4989 int height = window_box_height (w);
4994 struct buffer *old_buffer; 4990 struct buffer *old_buffer;
4995 int bottom_y; 4991 int bottom_y;
4992 void *itdata = NULL;
4996 4993
4997 if (XBUFFER (w->buffer) != current_buffer) 4994 if (XBUFFER (w->buffer) != current_buffer)
4998 { 4995 {
@@ -5012,9 +5009,11 @@ displayed_window_lines (struct window *w)
5012 else 5009 else
5013 SET_TEXT_POS_FROM_MARKER (start, w->start); 5010 SET_TEXT_POS_FROM_MARKER (start, w->start);
5014 5011
5012 itdata = bidi_shelve_cache ();
5015 start_display (&it, w, start); 5013 start_display (&it, w, start);
5016 move_it_vertically (&it, height); 5014 move_it_vertically (&it, height);
5017 bottom_y = line_bottom_y (&it); 5015 bottom_y = line_bottom_y (&it);
5016 bidi_unshelve_cache (itdata);
5018 5017
5019 /* rms: On a non-window display, 5018 /* rms: On a non-window display,
5020 the value of it.vpos at the bottom of the screen 5019 the value of it.vpos at the bottom of the screen
@@ -5113,12 +5112,14 @@ and redisplay normally--don't erase and redraw the frame. */)
5113 { 5112 {
5114 struct it it; 5113 struct it it;
5115 struct text_pos pt; 5114 struct text_pos pt;
5115 void *itdata = bidi_shelve_cache ();
5116 5116
5117 SET_TEXT_POS (pt, PT, PT_BYTE); 5117 SET_TEXT_POS (pt, PT, PT_BYTE);
5118 start_display (&it, w, pt); 5118 start_display (&it, w, pt);
5119 move_it_vertically_backward (&it, window_box_height (w) / 2); 5119 move_it_vertically_backward (&it, window_box_height (w) / 2);
5120 charpos = IT_CHARPOS (it); 5120 charpos = IT_CHARPOS (it);
5121 bytepos = IT_BYTEPOS (it); 5121 bytepos = IT_BYTEPOS (it);
5122 bidi_unshelve_cache (itdata);
5122 } 5123 }
5123 else if (iarg < 0) 5124 else if (iarg < 0)
5124 { 5125 {
@@ -5127,6 +5128,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5127 int nlines = -iarg; 5128 int nlines = -iarg;
5128 int extra_line_spacing; 5129 int extra_line_spacing;
5129 int h = window_box_height (w); 5130 int h = window_box_height (w);
5131 void *itdata = bidi_shelve_cache ();
5130 5132
5131 iarg = - max (-iarg, this_scroll_margin); 5133 iarg = - max (-iarg, this_scroll_margin);
5132 5134
@@ -5164,7 +5166,10 @@ and redisplay normally--don't erase and redraw the frame. */)
5164 h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing); 5166 h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
5165 } 5167 }
5166 if (h <= 0) 5168 if (h <= 0)
5167 return Qnil; 5169 {
5170 bidi_unshelve_cache (itdata);
5171 return Qnil;
5172 }
5168 5173
5169 /* Now find the new top line (starting position) of the window. */ 5174 /* Now find the new top line (starting position) of the window. */
5170 start_display (&it, w, pt); 5175 start_display (&it, w, pt);
@@ -5184,6 +5189,8 @@ and redisplay normally--don't erase and redraw the frame. */)
5184 5189
5185 charpos = IT_CHARPOS (it); 5190 charpos = IT_CHARPOS (it);
5186 bytepos = IT_BYTEPOS (it); 5191 bytepos = IT_BYTEPOS (it);
5192
5193 bidi_unshelve_cache (itdata);
5187 } 5194 }
5188 else 5195 else
5189 { 5196 {
@@ -5350,8 +5357,7 @@ struct saved_window
5350{ 5357{
5351 struct vectorlike_header header; 5358 struct vectorlike_header header;
5352 5359
5353 Lisp_Object window, clone_number; 5360 Lisp_Object window, buffer, start, pointm, mark;
5354 Lisp_Object buffer, start, pointm, mark;
5355 Lisp_Object left_col, top_line, total_cols, total_lines; 5361 Lisp_Object left_col, top_line, total_cols, total_lines;
5356 Lisp_Object normal_cols, normal_lines; 5362 Lisp_Object normal_cols, normal_lines;
5357 Lisp_Object hscroll, min_hscroll; 5363 Lisp_Object hscroll, min_hscroll;
@@ -5570,7 +5576,6 @@ the return value is nil. Otherwise the value is t. */)
5570 } 5576 }
5571 } 5577 }
5572 5578
5573 w->clone_number = p->clone_number;
5574 /* If we squirreled away the buffer in the window's height, 5579 /* If we squirreled away the buffer in the window's height,
5575 restore it now. */ 5580 restore it now. */
5576 if (BUFFERP (w->total_lines)) 5581 if (BUFFERP (w->total_lines))
@@ -5853,7 +5858,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
5853 5858
5854 XSETFASTINT (w->temslot, i); i++; 5859 XSETFASTINT (w->temslot, i); i++;
5855 p->window = window; 5860 p->window = window;
5856 p->clone_number = w->clone_number;
5857 p->buffer = w->buffer; 5861 p->buffer = w->buffer;
5858 p->left_col = w->left_col; 5862 p->left_col = w->left_col;
5859 p->top_line = w->top_line; 5863 p->top_line = w->top_line;
@@ -6457,8 +6461,8 @@ syms_of_window (void)
6457 DEFSYM (Qwindow_live_p, "window-live-p"); 6461 DEFSYM (Qwindow_live_p, "window-live-p");
6458 DEFSYM (Qwindow_deletable_p, "window-deletable-p"); 6462 DEFSYM (Qwindow_deletable_p, "window-deletable-p");
6459 DEFSYM (Qdelete_window, "delete-window"); 6463 DEFSYM (Qdelete_window, "delete-window");
6460 DEFSYM (Qresize_root_window, "resize-root-window"); 6464 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
6461 DEFSYM (Qresize_root_window_vertically, "resize-root-window-vertically"); 6465 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
6462 DEFSYM (Qsafe, "safe"); 6466 DEFSYM (Qsafe, "safe");
6463 DEFSYM (Qdisplay_buffer, "display-buffer"); 6467 DEFSYM (Qdisplay_buffer, "display-buffer");
6464 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows"); 6468 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
@@ -6598,7 +6602,6 @@ function `window-nest' and altered by the function `set-window-nest'. */);
6598 defsubr (&Sset_frame_selected_window); 6602 defsubr (&Sset_frame_selected_window);
6599 defsubr (&Spos_visible_in_window_p); 6603 defsubr (&Spos_visible_in_window_p);
6600 defsubr (&Swindow_line_height); 6604 defsubr (&Swindow_line_height);
6601 defsubr (&Swindow_clone_number);
6602 defsubr (&Swindow_buffer); 6605 defsubr (&Swindow_buffer);
6603 defsubr (&Swindow_parent); 6606 defsubr (&Swindow_parent);
6604 defsubr (&Swindow_top_child); 6607 defsubr (&Swindow_top_child);
@@ -6648,7 +6651,6 @@ function `window-nest' and altered by the function `set-window-nest'. */);
6648 defsubr (&Sdelete_window_internal); 6651 defsubr (&Sdelete_window_internal);
6649 defsubr (&Sresize_mini_window_internal); 6652 defsubr (&Sresize_mini_window_internal);
6650 defsubr (&Sset_window_buffer); 6653 defsubr (&Sset_window_buffer);
6651 defsubr (&Sset_window_clone_number);
6652 defsubr (&Srun_window_configuration_change_hook); 6654 defsubr (&Srun_window_configuration_change_hook);
6653 defsubr (&Sselect_window); 6655 defsubr (&Sselect_window);
6654 defsubr (&Sforce_window_update); 6656 defsubr (&Sforce_window_update);
diff --git a/src/window.h b/src/window.h
index c3f59e4b116..485734e907e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -165,10 +165,6 @@ struct window
165 /* Unique number of window assigned when it was created. */ 165 /* Unique number of window assigned when it was created. */
166 Lisp_Object sequence_number; 166 Lisp_Object sequence_number;
167 167
168 /* Sequence number of window this window was cloned from. Identic
169 to sequence number if window was not cloned. */
170 Lisp_Object clone_number;
171
172 /* No permanent meaning; used by save-window-excursion's 168 /* No permanent meaning; used by save-window-excursion's
173 bookkeeping. */ 169 bookkeeping. */
174 Lisp_Object temslot; 170 Lisp_Object temslot;
diff --git a/src/xdisp.c b/src/xdisp.c
index 31506e2247b..c02de7225e1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -129,9 +129,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
129 argument. 129 argument.
130 130
131 Iteration over things to be displayed is then simple. It is 131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator. 132 started by initializing an iterator with a call to init_iterator,
133 Calls to get_next_display_element fill the iterator structure with 133 passing it the buffer position where to start iteration. For
134 relevant information about the next thing to display. Calls to 134 iteration over strings, pass -1 as the position to init_iterator,
135 and call reseat_to_string when the string is ready, to initialize
136 the iterator for that string. Thereafter, calls to
137 get_next_display_element fill the iterator structure with relevant
138 information about the next thing to display. Calls to
135 set_iterator_to_next move the iterator to the next thing. 139 set_iterator_to_next move the iterator to the next thing.
136 140
137 Besides this, an iterator also contains information about the 141 Besides this, an iterator also contains information about the
@@ -592,6 +596,29 @@ int current_mode_line_height, current_header_line_height;
592 596
593#define TEXT_PROP_DISTANCE_LIMIT 100 597#define TEXT_PROP_DISTANCE_LIMIT 100
594 598
599/* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
600 iterator state and later restore it. This is needed because the
601 bidi iterator on bidi.c keeps a stacked cache of its states, which
602 is really a singleton. When we use scratch iterator objects to
603 move around the buffer, we can cause the bidi cache to be pushed or
604 popped, and therefore we need to restore the cache state when we
605 return to the original iterator. */
606#define SAVE_IT(ITCOPY,ITORIG,CACHE) \
607 do { \
608 if (CACHE) \
609 xfree (CACHE); \
610 ITCOPY = ITORIG; \
611 CACHE = bidi_shelve_cache(); \
612 } while (0)
613
614#define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
615 do { \
616 if (pITORIG != pITCOPY) \
617 *(pITORIG) = *(pITCOPY); \
618 bidi_unshelve_cache (CACHE); \
619 CACHE = NULL; \
620 } while (0)
621
595#if GLYPH_DEBUG 622#if GLYPH_DEBUG
596 623
597/* Non-zero means print traces of redisplay if compiled with 624/* Non-zero means print traces of redisplay if compiled with
@@ -1198,6 +1225,7 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1198 int *rtop, int *rbot, int *rowh, int *vpos) 1225 int *rtop, int *rbot, int *rowh, int *vpos)
1199{ 1226{
1200 struct it it; 1227 struct it it;
1228 void *itdata = bidi_shelve_cache ();
1201 struct text_pos top; 1229 struct text_pos top;
1202 int visible_p = 0; 1230 int visible_p = 0;
1203 struct buffer *old_buffer = NULL; 1231 struct buffer *old_buffer = NULL;
@@ -1228,13 +1256,21 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1228 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1, 1256 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1229 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); 1257 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1230 1258
1231 if (charpos >= 0 && IT_CHARPOS (it) >= charpos) 1259 if (charpos >= 0
1260 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1261 && IT_CHARPOS (it) >= charpos)
1262 /* When scanning backwards under bidi iteration, move_it_to
1263 stops at or _before_ CHARPOS, because it stops at or to
1264 the _right_ of the character at CHARPOS. */
1265 || (it.bidi_p && it.bidi_it.scan_dir == -1
1266 && IT_CHARPOS (it) <= charpos)))
1232 { 1267 {
1233 /* We have reached CHARPOS, or passed it. How the call to 1268 /* We have reached CHARPOS, or passed it. How the call to
1234 move_it_to can overshoot: (i) If CHARPOS is on invisible 1269 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1235 text, move_it_to stops at the end of the invisible text, 1270 or covered by a display property, move_it_to stops at the end
1236 after CHARPOS. (ii) If CHARPOS is in a display vector, 1271 of the invisible text, to the right of CHARPOS. (ii) If
1237 move_it_to stops on its last glyph. */ 1272 CHARPOS is in a display vector, move_it_to stops on its last
1273 glyph. */
1238 int top_x = it.current_x; 1274 int top_x = it.current_x;
1239 int top_y = it.current_y; 1275 int top_y = it.current_y;
1240 enum it_method it_method = it.method; 1276 enum it_method it_method = it.method;
@@ -1283,15 +1319,18 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1283 } 1319 }
1284 else 1320 else
1285 { 1321 {
1322 /* We were asked to provide info about WINDOW_END. */
1286 struct it it2; 1323 struct it it2;
1324 void *it2data = NULL;
1287 1325
1288 it2 = it; 1326 SAVE_IT (it2, it, it2data);
1289 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n') 1327 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1290 move_it_by_lines (&it, 1); 1328 move_it_by_lines (&it, 1);
1291 if (charpos < IT_CHARPOS (it) 1329 if (charpos < IT_CHARPOS (it)
1292 || (it.what == IT_EOB && charpos == IT_CHARPOS (it))) 1330 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1293 { 1331 {
1294 visible_p = 1; 1332 visible_p = 1;
1333 RESTORE_IT (&it2, &it2, it2data);
1295 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS); 1334 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1296 *x = it2.current_x; 1335 *x = it2.current_x;
1297 *y = it2.current_y + it2.max_ascent - it2.ascent; 1336 *y = it2.current_y + it2.max_ascent - it2.ascent;
@@ -1304,7 +1343,10 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1304 WINDOW_HEADER_LINE_HEIGHT (w)))); 1343 WINDOW_HEADER_LINE_HEIGHT (w))));
1305 *vpos = it2.vpos; 1344 *vpos = it2.vpos;
1306 } 1345 }
1346 else
1347 xfree (it2data);
1307 } 1348 }
1349 bidi_unshelve_cache (itdata);
1308 1350
1309 if (old_buffer) 1351 if (old_buffer)
1310 set_buffer_internal_1 (old_buffer); 1352 set_buffer_internal_1 (old_buffer);
@@ -2212,8 +2254,7 @@ safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2212 This is for debugging. It is too slow to do unconditionally. */ 2254 This is for debugging. It is too slow to do unconditionally. */
2213 2255
2214static void 2256static void
2215check_it (it) 2257check_it (struct it *it)
2216 struct it *it;
2217{ 2258{
2218 if (it->method == GET_FROM_STRING) 2259 if (it->method == GET_FROM_STRING)
2219 { 2260 {
@@ -2343,6 +2384,10 @@ init_iterator (struct it *it, struct window *w,
2343 it->base_face_id = remapped_base_face_id; 2384 it->base_face_id = remapped_base_face_id;
2344 it->string = Qnil; 2385 it->string = Qnil;
2345 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1; 2386 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2387 it->paragraph_embedding = L2R;
2388 it->bidi_it.string.lstring = Qnil;
2389 it->bidi_it.string.s = NULL;
2390 it->bidi_it.string.bufpos = 0;
2346 2391
2347 /* The window in which we iterate over current_buffer: */ 2392 /* The window in which we iterate over current_buffer: */
2348 XSETWINDOW (it->window, w); 2393 XSETWINDOW (it->window, w);
@@ -2399,13 +2444,6 @@ init_iterator (struct it *it, struct window *w,
2399 /* Are multibyte characters enabled in current_buffer? */ 2444 /* Are multibyte characters enabled in current_buffer? */
2400 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); 2445 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2401 2446
2402 /* Do we need to reorder bidirectional text? Not if this is a
2403 unibyte buffer: by definition, none of the single-byte characters
2404 are strong R2L, so no reordering is needed. And bidi.c doesn't
2405 support unibyte buffers anyway. */
2406 it->bidi_p
2407 = !NILP (BVAR (current_buffer, bidi_display_reordering)) && it->multibyte_p;
2408
2409 /* Non-zero if we should highlight the region. */ 2447 /* Non-zero if we should highlight the region. */
2410 highlight_region_p 2448 highlight_region_p
2411 = (!NILP (Vtransient_mark_mode) 2449 = (!NILP (Vtransient_mark_mode)
@@ -2555,21 +2593,6 @@ init_iterator (struct it *it, struct window *w,
2555 it->start_of_box_run_p = 1; 2593 it->start_of_box_run_p = 1;
2556 } 2594 }
2557 2595
2558 /* If we are to reorder bidirectional text, init the bidi
2559 iterator. */
2560 if (it->bidi_p)
2561 {
2562 /* Note the paragraph direction that this buffer wants to
2563 use. */
2564 if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right))
2565 it->paragraph_embedding = L2R;
2566 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left))
2567 it->paragraph_embedding = R2L;
2568 else
2569 it->paragraph_embedding = NEUTRAL_DIR;
2570 bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it);
2571 }
2572
2573 /* If a buffer position was specified, set the iterator there, 2596 /* If a buffer position was specified, set the iterator there,
2574 getting overlays and face properties from that position. */ 2597 getting overlays and face properties from that position. */
2575 if (charpos >= BUF_BEG (current_buffer)) 2598 if (charpos >= BUF_BEG (current_buffer))
@@ -2585,6 +2608,32 @@ init_iterator (struct it *it, struct window *w,
2585 IT_BYTEPOS (*it) = bytepos; 2608 IT_BYTEPOS (*it) = bytepos;
2586 2609
2587 it->start = it->current; 2610 it->start = it->current;
2611 /* Do we need to reorder bidirectional text? Not if this is a
2612 unibyte buffer: by definition, none of the single-byte
2613 characters are strong R2L, so no reordering is needed. And
2614 bidi.c doesn't support unibyte buffers anyway. */
2615 it->bidi_p =
2616 !NILP (BVAR (current_buffer, bidi_display_reordering))
2617 && it->multibyte_p;
2618
2619 /* If we are to reorder bidirectional text, init the bidi
2620 iterator. */
2621 if (it->bidi_p)
2622 {
2623 /* Note the paragraph direction that this buffer wants to
2624 use. */
2625 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2626 Qleft_to_right))
2627 it->paragraph_embedding = L2R;
2628 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2629 Qright_to_left))
2630 it->paragraph_embedding = R2L;
2631 else
2632 it->paragraph_embedding = NEUTRAL_DIR;
2633 bidi_unshelve_cache (NULL);
2634 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2635 &it->bidi_it);
2636 }
2588 2637
2589 /* Compute faces etc. */ 2638 /* Compute faces etc. */
2590 reseat (it, it->current.pos, 1); 2639 reseat (it, it->current.pos, 1);
@@ -2906,6 +2955,7 @@ handle_stop (struct it *it)
2906 { 2955 {
2907 it->ignore_overlay_strings_at_pos_p = 1; 2956 it->ignore_overlay_strings_at_pos_p = 1;
2908 it->string_from_display_prop_p = 0; 2957 it->string_from_display_prop_p = 0;
2958 it->from_disp_prop_p = 0;
2909 handle_overlay_change_p = 0; 2959 handle_overlay_change_p = 0;
2910 } 2960 }
2911 handled = HANDLED_RECOMPUTE_PROPS; 2961 handled = HANDLED_RECOMPUTE_PROPS;
@@ -3087,37 +3137,50 @@ next_overlay_change (EMACS_INT pos)
3087 return endpos; 3137 return endpos;
3088} 3138}
3089 3139
3090/* Return the character position of a display string at or after CHARPOS. 3140/* Return the character position of a display string at or after
3091 If no display string exists at or after CHARPOS, return ZV. A 3141 position specified by POSITION. If no display string exists at or
3092 display string is either an overlay with `display' property whose 3142 after POSITION, return ZV. A display string is either an overlay
3093 value is a string, or a `display' text property whose value is a 3143 with `display' property whose value is a string, or a `display'
3094 string. FRAME_WINDOW_P is non-zero when we are displaying a window 3144 text property whose value is a string. STRING is data about the
3145 string to iterate; if STRING->lstring is nil, we are iterating a
3146 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3095 on a GUI frame. */ 3147 on a GUI frame. */
3096EMACS_INT 3148EMACS_INT
3097compute_display_string_pos (EMACS_INT charpos, int frame_window_p) 3149compute_display_string_pos (struct text_pos *position,
3150 struct bidi_string_data *string, int frame_window_p)
3098{ 3151{
3099 /* FIXME: Support display properties on strings (object = Qnil means 3152 /* OBJECT = nil means current buffer. */
3100 current buffer). */ 3153 Lisp_Object object =
3101 Lisp_Object object = Qnil; 3154 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3102 Lisp_Object pos, spec; 3155 Lisp_Object pos, spec;
3103 struct text_pos position; 3156 int string_p = (string && (STRINGP (string->lstring) || string->s));
3104 EMACS_INT bufpos; 3157 EMACS_INT eob = string_p ? string->schars : ZV;
3105 3158 EMACS_INT begb = string_p ? 0 : BEGV;
3106 if (charpos >= ZV) 3159 EMACS_INT bufpos, charpos = CHARPOS (*position);
3107 return ZV; 3160 struct text_pos tpos;
3161
3162 if (charpos >= eob
3163 /* We don't support display properties whose values are strings
3164 that have display string properties. */
3165 || string->from_disp_str
3166 /* C strings cannot have display properties. */
3167 || (string->s && !STRINGP (object)))
3168 return eob;
3108 3169
3109 /* If the character at CHARPOS is where the display string begins, 3170 /* If the character at CHARPOS is where the display string begins,
3110 return CHARPOS. */ 3171 return CHARPOS. */
3111 pos = make_number (charpos); 3172 pos = make_number (charpos);
3112 CHARPOS (position) = charpos; 3173 if (STRINGP (object))
3113 BYTEPOS (position) = CHAR_TO_BYTE (charpos); 3174 bufpos = string->bufpos;
3114 bufpos = charpos; /* FIXME! support strings as well */ 3175 else
3176 bufpos = charpos;
3177 tpos = *position;
3115 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object)) 3178 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3116 && (charpos <= BEGV 3179 && (charpos <= begb
3117 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay, 3180 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3118 object), 3181 object),
3119 spec)) 3182 spec))
3120 && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos, 3183 && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3121 frame_window_p)) 3184 frame_window_p))
3122 return charpos; 3185 return charpos;
3123 3186
@@ -3125,17 +3188,21 @@ compute_display_string_pos (EMACS_INT charpos, int frame_window_p)
3125 that will replace the underlying text when displayed. */ 3188 that will replace the underlying text when displayed. */
3126 do { 3189 do {
3127 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil); 3190 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3128 CHARPOS (position) = XFASTINT (pos); 3191 CHARPOS (tpos) = XFASTINT (pos);
3129 BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position)); 3192 if (STRINGP (object))
3130 if (CHARPOS (position) >= ZV) 3193 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3194 else
3195 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3196 if (CHARPOS (tpos) >= eob)
3131 break; 3197 break;
3132 spec = Fget_char_property (pos, Qdisplay, object); 3198 spec = Fget_char_property (pos, Qdisplay, object);
3133 bufpos = CHARPOS (position); /* FIXME! support strings as well */ 3199 if (!STRINGP (object))
3200 bufpos = CHARPOS (tpos);
3134 } while (NILP (spec) 3201 } while (NILP (spec)
3135 || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos, 3202 || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3136 frame_window_p)); 3203 frame_window_p));
3137 3204
3138 return CHARPOS (position); 3205 return CHARPOS (tpos);
3139} 3206}
3140 3207
3141/* Return the character position of the end of the display string that 3208/* Return the character position of the end of the display string that
@@ -3143,15 +3210,17 @@ compute_display_string_pos (EMACS_INT charpos, int frame_window_p)
3143 `display' property whose value is a string or a `display' text 3210 `display' property whose value is a string or a `display' text
3144 property whose value is a string. */ 3211 property whose value is a string. */
3145EMACS_INT 3212EMACS_INT
3146compute_display_string_end (EMACS_INT charpos) 3213compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string)
3147{ 3214{
3148 /* FIXME: Support display properties on strings (object = Qnil means 3215 /* OBJECT = nil means current buffer. */
3149 current buffer). */ 3216 Lisp_Object object =
3150 Lisp_Object object = Qnil; 3217 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3151 Lisp_Object pos = make_number (charpos); 3218 Lisp_Object pos = make_number (charpos);
3219 EMACS_INT eob =
3220 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3152 3221
3153 if (charpos >= ZV) 3222 if (charpos >= eob || (string->s && !STRINGP (object)))
3154 return ZV; 3223 return eob;
3155 3224
3156 if (NILP (Fget_char_property (pos, Qdisplay, object))) 3225 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3157 abort (); 3226 abort ();
@@ -3444,21 +3513,23 @@ underlying_face_id (struct it *it)
3444 3513
3445 3514
3446/* Compute the face one character before or after the current position 3515/* Compute the face one character before or after the current position
3447 of IT. BEFORE_P non-zero means get the face in front of IT's 3516 of IT, in the visual order. BEFORE_P non-zero means get the face
3448 position. Value is the id of the face. */ 3517 in front (to the left in L2R paragraphs, to the right in R2L
3518 paragraphs) of IT's screen position. Value is the ID of the face. */
3449 3519
3450static int 3520static int
3451face_before_or_after_it_pos (struct it *it, int before_p) 3521face_before_or_after_it_pos (struct it *it, int before_p)
3452{ 3522{
3453 int face_id, limit; 3523 int face_id, limit;
3454 EMACS_INT next_check_charpos; 3524 EMACS_INT next_check_charpos;
3455 struct text_pos pos; 3525 struct it it_copy;
3526 void *it_copy_data = NULL;
3456 3527
3457 xassert (it->s == NULL); 3528 xassert (it->s == NULL);
3458 3529
3459 if (STRINGP (it->string)) 3530 if (STRINGP (it->string))
3460 { 3531 {
3461 EMACS_INT bufpos; 3532 EMACS_INT bufpos, charpos;
3462 int base_face_id; 3533 int base_face_id;
3463 3534
3464 /* No face change past the end of the string (for the case 3535 /* No face change past the end of the string (for the case
@@ -3468,16 +3539,59 @@ face_before_or_after_it_pos (struct it *it, int before_p)
3468 || (IT_STRING_CHARPOS (*it) == 0 && before_p)) 3539 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3469 return it->face_id; 3540 return it->face_id;
3470 3541
3471 /* Set pos to the position before or after IT's current position. */ 3542 if (!it->bidi_p)
3472 if (before_p) 3543 {
3473 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string); 3544 /* Set charpos to the position before or after IT's current
3545 position, in the logical order, which in the non-bidi
3546 case is the same as the visual order. */
3547 if (before_p)
3548 charpos = IT_STRING_CHARPOS (*it) - 1;
3549 else if (it->what == IT_COMPOSITION)
3550 /* For composition, we must check the character after the
3551 composition. */
3552 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3553 else
3554 charpos = IT_STRING_CHARPOS (*it) + 1;
3555 }
3474 else 3556 else
3475 /* For composition, we must check the character after the 3557 {
3476 composition. */ 3558 if (before_p)
3477 pos = (it->what == IT_COMPOSITION 3559 {
3478 ? string_pos (IT_STRING_CHARPOS (*it) 3560 /* With bidi iteration, the character before the current
3479 + it->cmp_it.nchars, it->string) 3561 in the visual order cannot be found by simple
3480 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); 3562 iteration, because "reverse" reordering is not
3563 supported. Instead, we need to use the move_it_*
3564 family of functions. */
3565 /* Ignore face changes before the first visible
3566 character on this display line. */
3567 if (it->current_x <= it->first_visible_x)
3568 return it->face_id;
3569 SAVE_IT (it_copy, *it, it_copy_data);
3570 /* Implementation note: Since move_it_in_display_line
3571 works in the iterator geometry, and thinks the first
3572 character is always the leftmost, even in R2L lines,
3573 we don't need to distinguish between the R2L and L2R
3574 cases here. */
3575 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3576 it_copy.current_x - 1, MOVE_TO_X);
3577 charpos = IT_STRING_CHARPOS (it_copy);
3578 RESTORE_IT (it, it, it_copy_data);
3579 }
3580 else
3581 {
3582 /* Set charpos to the string position of the character
3583 that comes after IT's current position in the visual
3584 order. */
3585 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3586
3587 it_copy = *it;
3588 while (n--)
3589 bidi_move_to_visually_next (&it_copy.bidi_it);
3590
3591 charpos = it_copy.bidi_it.charpos;
3592 }
3593 }
3594 xassert (0 <= charpos && charpos <= SCHARS (it->string));
3481 3595
3482 if (it->current.overlay_string_index >= 0) 3596 if (it->current.overlay_string_index >= 0)
3483 bufpos = IT_CHARPOS (*it); 3597 bufpos = IT_CHARPOS (*it);
@@ -3489,7 +3603,7 @@ face_before_or_after_it_pos (struct it *it, int before_p)
3489 /* Get the face for ASCII, or unibyte. */ 3603 /* Get the face for ASCII, or unibyte. */
3490 face_id = face_at_string_position (it->w, 3604 face_id = face_at_string_position (it->w,
3491 it->string, 3605 it->string,
3492 CHARPOS (pos), 3606 charpos,
3493 bufpos, 3607 bufpos,
3494 it->region_beg_charpos, 3608 it->region_beg_charpos,
3495 it->region_end_charpos, 3609 it->region_end_charpos,
@@ -3501,16 +3615,19 @@ face_before_or_after_it_pos (struct it *it, int before_p)
3501 suitable for unibyte text if IT->string is unibyte. */ 3615 suitable for unibyte text if IT->string is unibyte. */
3502 if (STRING_MULTIBYTE (it->string)) 3616 if (STRING_MULTIBYTE (it->string))
3503 { 3617 {
3504 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos); 3618 struct text_pos pos1 = string_pos (charpos, it->string);
3619 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
3505 int c, len; 3620 int c, len;
3506 struct face *face = FACE_FROM_ID (it->f, face_id); 3621 struct face *face = FACE_FROM_ID (it->f, face_id);
3507 3622
3508 c = string_char_and_length (p, &len); 3623 c = string_char_and_length (p, &len);
3509 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string); 3624 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
3510 } 3625 }
3511 } 3626 }
3512 else 3627 else
3513 { 3628 {
3629 struct text_pos pos;
3630
3514 if ((IT_CHARPOS (*it) >= ZV && !before_p) 3631 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3515 || (IT_CHARPOS (*it) <= BEGV && before_p)) 3632 || (IT_CHARPOS (*it) <= BEGV && before_p))
3516 return it->face_id; 3633 return it->face_id;
@@ -3518,17 +3635,63 @@ face_before_or_after_it_pos (struct it *it, int before_p)
3518 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT; 3635 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3519 pos = it->current.pos; 3636 pos = it->current.pos;
3520 3637
3521 if (before_p) 3638 if (!it->bidi_p)
3522 DEC_TEXT_POS (pos, it->multibyte_p); 3639 {
3640 if (before_p)
3641 DEC_TEXT_POS (pos, it->multibyte_p);
3642 else
3643 {
3644 if (it->what == IT_COMPOSITION)
3645 {
3646 /* For composition, we must check the position after
3647 the composition. */
3648 pos.charpos += it->cmp_it.nchars;
3649 pos.bytepos += it->len;
3650 }
3651 else
3652 INC_TEXT_POS (pos, it->multibyte_p);
3653 }
3654 }
3523 else 3655 else
3524 { 3656 {
3525 if (it->what == IT_COMPOSITION) 3657 if (before_p)
3526 /* For composition, we must check the position after the 3658 {
3527 composition. */ 3659 /* With bidi iteration, the character before the current
3528 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len; 3660 in the visual order cannot be found by simple
3661 iteration, because "reverse" reordering is not
3662 supported. Instead, we need to use the move_it_*
3663 family of functions. */
3664 /* Ignore face changes before the first visible
3665 character on this display line. */
3666 if (it->current_x <= it->first_visible_x)
3667 return it->face_id;
3668 SAVE_IT (it_copy, *it, it_copy_data);
3669 /* Implementation note: Since move_it_in_display_line
3670 works in the iterator geometry, and thinks the first
3671 character is always the leftmost, even in R2L lines,
3672 we don't need to distinguish between the R2L and L2R
3673 cases here. */
3674 move_it_in_display_line (&it_copy, ZV,
3675 it_copy.current_x - 1, MOVE_TO_X);
3676 pos = it_copy.current.pos;
3677 RESTORE_IT (it, it, it_copy_data);
3678 }
3529 else 3679 else
3530 INC_TEXT_POS (pos, it->multibyte_p); 3680 {
3681 /* Set charpos to the buffer position of the character
3682 that comes after IT's current position in the visual
3683 order. */
3684 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3685
3686 it_copy = *it;
3687 while (n--)
3688 bidi_move_to_visually_next (&it_copy.bidi_it);
3689
3690 SET_TEXT_POS (pos,
3691 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
3692 }
3531 } 3693 }
3694 xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
3532 3695
3533 /* Determine face for CHARSET_ASCII, or unibyte. */ 3696 /* Determine face for CHARSET_ASCII, or unibyte. */
3534 face_id = face_at_buffer_position (it->w, 3697 face_id = face_at_buffer_position (it->w,
@@ -3579,6 +3742,8 @@ handle_invisible_prop (struct it *it)
3579 if (!NILP (prop) 3742 if (!NILP (prop)
3580 && IT_STRING_CHARPOS (*it) < it->end_charpos) 3743 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3581 { 3744 {
3745 EMACS_INT endpos;
3746
3582 handled = HANDLED_RECOMPUTE_PROPS; 3747 handled = HANDLED_RECOMPUTE_PROPS;
3583 3748
3584 /* Get the position at which the next change of the 3749 /* Get the position at which the next change of the
@@ -3593,12 +3758,37 @@ handle_invisible_prop (struct it *it)
3593 change in the property is at position end_charpos. 3758 change in the property is at position end_charpos.
3594 Move IT's current position to that position. */ 3759 Move IT's current position to that position. */
3595 if (INTEGERP (end_charpos) 3760 if (INTEGERP (end_charpos)
3596 && XFASTINT (end_charpos) < XFASTINT (limit)) 3761 && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
3597 { 3762 {
3598 struct text_pos old; 3763 struct text_pos old;
3764 EMACS_INT oldpos;
3765
3599 old = it->current.string_pos; 3766 old = it->current.string_pos;
3600 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos); 3767 oldpos = CHARPOS (old);
3601 compute_string_pos (&it->current.string_pos, old, it->string); 3768 if (it->bidi_p)
3769 {
3770 if (it->bidi_it.first_elt
3771 && it->bidi_it.charpos < SCHARS (it->string))
3772 bidi_paragraph_init (it->paragraph_embedding,
3773 &it->bidi_it, 1);
3774 /* Bidi-iterate out of the invisible text. */
3775 do
3776 {
3777 bidi_move_to_visually_next (&it->bidi_it);
3778 }
3779 while (oldpos <= it->bidi_it.charpos
3780 && it->bidi_it.charpos < endpos);
3781
3782 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
3783 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
3784 if (IT_CHARPOS (*it) >= endpos)
3785 it->prev_stop = endpos;
3786 }
3787 else
3788 {
3789 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3790 compute_string_pos (&it->current.string_pos, old, it->string);
3791 }
3602 } 3792 }
3603 else 3793 else
3604 { 3794 {
@@ -4250,6 +4440,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4250 it->method = GET_FROM_IMAGE; 4440 it->method = GET_FROM_IMAGE;
4251 it->from_overlay = Qnil; 4441 it->from_overlay = Qnil;
4252 it->face_id = face_id; 4442 it->face_id = face_id;
4443 it->from_disp_prop_p = 1;
4253 4444
4254 /* Say that we haven't consumed the characters with 4445 /* Say that we haven't consumed the characters with
4255 `display' property yet. The call to pop_it in 4446 `display' property yet. The call to pop_it in
@@ -4332,6 +4523,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4332 when we are finished with the glyph property value. */ 4523 when we are finished with the glyph property value. */
4333 push_it (it, position); 4524 push_it (it, position);
4334 it->from_overlay = overlay; 4525 it->from_overlay = overlay;
4526 it->from_disp_prop_p = 1;
4335 4527
4336 if (NILP (location)) 4528 if (NILP (location))
4337 it->area = TEXT_AREA; 4529 it->area = TEXT_AREA;
@@ -4349,12 +4541,34 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4349 it->end_charpos = it->string_nchars = SCHARS (it->string); 4541 it->end_charpos = it->string_nchars = SCHARS (it->string);
4350 it->method = GET_FROM_STRING; 4542 it->method = GET_FROM_STRING;
4351 it->stop_charpos = 0; 4543 it->stop_charpos = 0;
4544 it->prev_stop = 0;
4545 it->base_level_stop = 0;
4352 it->string_from_display_prop_p = 1; 4546 it->string_from_display_prop_p = 1;
4353 /* Say that we haven't consumed the characters with 4547 /* Say that we haven't consumed the characters with
4354 `display' property yet. The call to pop_it in 4548 `display' property yet. The call to pop_it in
4355 set_iterator_to_next will clean this up. */ 4549 set_iterator_to_next will clean this up. */
4356 if (BUFFERP (object)) 4550 if (BUFFERP (object))
4357 *position = start_pos; 4551 *position = start_pos;
4552
4553 /* Force paragraph direction to be that of the parent
4554 object. If the parent object's paragraph direction is
4555 not yet determined, default to L2R. */
4556 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
4557 it->paragraph_embedding = it->bidi_it.paragraph_dir;
4558 else
4559 it->paragraph_embedding = L2R;
4560
4561 /* Set up the bidi iterator for this display string. */
4562 if (it->bidi_p)
4563 {
4564 it->bidi_it.string.lstring = it->string;
4565 it->bidi_it.string.s = NULL;
4566 it->bidi_it.string.schars = it->end_charpos;
4567 it->bidi_it.string.bufpos = bufpos;
4568 it->bidi_it.string.from_disp_str = 1;
4569 it->bidi_it.string.unibyte = !it->multibyte_p;
4570 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4571 }
4358 } 4572 }
4359 else if (CONSP (value) && EQ (XCAR (value), Qspace)) 4573 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4360 { 4574 {
@@ -4610,6 +4824,11 @@ handle_composition_prop (struct it *it)
4610 && COMPOSITION_VALID_P (start, end, prop) 4824 && COMPOSITION_VALID_P (start, end, prop)
4611 && (STRINGP (it->string) || (PT <= start || PT >= end))) 4825 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4612 { 4826 {
4827 if (start < pos)
4828 /* As we can't handle this situation (perhaps font-lock added
4829 a new composition), we just return here hoping that next
4830 redisplay will detect this composition much earlier. */
4831 return HANDLED_NORMALLY;
4613 if (start != pos) 4832 if (start != pos)
4614 { 4833 {
4615 if (STRINGP (it->string)) 4834 if (STRINGP (it->string))
@@ -4718,6 +4937,20 @@ next_overlay_string (struct it *it)
4718 it->stop_charpos = 0; 4937 it->stop_charpos = 0;
4719 if (it->cmp_it.stop_pos >= 0) 4938 if (it->cmp_it.stop_pos >= 0)
4720 it->cmp_it.stop_pos = 0; 4939 it->cmp_it.stop_pos = 0;
4940 it->prev_stop = 0;
4941 it->base_level_stop = 0;
4942
4943 /* Set up the bidi iterator for this overlay string. */
4944 if (it->bidi_p)
4945 {
4946 it->bidi_it.string.lstring = it->string;
4947 it->bidi_it.string.s = NULL;
4948 it->bidi_it.string.schars = SCHARS (it->string);
4949 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
4950 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
4951 it->bidi_it.string.unibyte = !it->multibyte_p;
4952 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4953 }
4721 } 4954 }
4722 4955
4723 CHECK_IT (it); 4956 CHECK_IT (it);
@@ -4984,8 +5217,32 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
4984 it->stop_charpos = 0; 5217 it->stop_charpos = 0;
4985 xassert (STRINGP (it->string)); 5218 xassert (STRINGP (it->string));
4986 it->end_charpos = SCHARS (it->string); 5219 it->end_charpos = SCHARS (it->string);
5220 it->prev_stop = 0;
5221 it->base_level_stop = 0;
4987 it->multibyte_p = STRING_MULTIBYTE (it->string); 5222 it->multibyte_p = STRING_MULTIBYTE (it->string);
4988 it->method = GET_FROM_STRING; 5223 it->method = GET_FROM_STRING;
5224 it->from_disp_prop_p = 0;
5225
5226 /* Force paragraph direction to be that of the parent
5227 buffer. */
5228 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5229 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5230 else
5231 it->paragraph_embedding = L2R;
5232
5233 /* Set up the bidi iterator for this overlay string. */
5234 if (it->bidi_p)
5235 {
5236 EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5237
5238 it->bidi_it.string.lstring = it->string;
5239 it->bidi_it.string.s = NULL;
5240 it->bidi_it.string.schars = SCHARS (it->string);
5241 it->bidi_it.string.bufpos = pos;
5242 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5243 it->bidi_it.string.unibyte = !it->multibyte_p;
5244 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5245 }
4989 return 1; 5246 return 1;
4990 } 5247 }
4991 5248
@@ -5064,19 +5321,30 @@ push_it (struct it *it, struct text_pos *position)
5064 p->string_from_display_prop_p = it->string_from_display_prop_p; 5321 p->string_from_display_prop_p = it->string_from_display_prop_p;
5065 p->display_ellipsis_p = 0; 5322 p->display_ellipsis_p = 0;
5066 p->line_wrap = it->line_wrap; 5323 p->line_wrap = it->line_wrap;
5324 p->bidi_p = it->bidi_p;
5325 p->paragraph_embedding = it->paragraph_embedding;
5326 p->from_disp_prop_p = it->from_disp_prop_p;
5067 ++it->sp; 5327 ++it->sp;
5328
5329 /* Save the state of the bidi iterator as well. */
5330 if (it->bidi_p)
5331 bidi_push_it (&it->bidi_it);
5068} 5332}
5069 5333
5070static void 5334static void
5071iterate_out_of_display_property (struct it *it) 5335iterate_out_of_display_property (struct it *it)
5072{ 5336{
5337 int buffer_p = BUFFERP (it->object);
5338 EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
5339 EMACS_INT bob = (buffer_p ? BEGV : 0);
5340
5073 /* Maybe initialize paragraph direction. If we are at the beginning 5341 /* Maybe initialize paragraph direction. If we are at the beginning
5074 of a new paragraph, next_element_from_buffer may not have a 5342 of a new paragraph, next_element_from_buffer may not have a
5075 chance to do that. */ 5343 chance to do that. */
5076 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV) 5344 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5077 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1); 5345 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5078 /* prev_stop can be zero, so check against BEGV as well. */ 5346 /* prev_stop can be zero, so check against BEGV as well. */
5079 while (it->bidi_it.charpos >= BEGV 5347 while (it->bidi_it.charpos >= bob
5080 && it->prev_stop <= it->bidi_it.charpos 5348 && it->prev_stop <= it->bidi_it.charpos
5081 && it->bidi_it.charpos < CHARPOS (it->position)) 5349 && it->bidi_it.charpos < CHARPOS (it->position))
5082 bidi_move_to_visually_next (&it->bidi_it); 5350 bidi_move_to_visually_next (&it->bidi_it);
@@ -5090,7 +5358,10 @@ iterate_out_of_display_property (struct it *it)
5090 { 5358 {
5091 SET_TEXT_POS (it->position, 5359 SET_TEXT_POS (it->position,
5092 it->bidi_it.charpos, it->bidi_it.bytepos); 5360 it->bidi_it.charpos, it->bidi_it.bytepos);
5093 it->current.pos = it->position; 5361 if (buffer_p)
5362 it->current.pos = it->position;
5363 else
5364 it->current.string_pos = it->position;
5094 } 5365 }
5095} 5366}
5096 5367
@@ -5104,6 +5375,7 @@ static void
5104pop_it (struct it *it) 5375pop_it (struct it *it)
5105{ 5376{
5106 struct iterator_stack_entry *p; 5377 struct iterator_stack_entry *p;
5378 int from_display_prop = it->from_disp_prop_p;
5107 5379
5108 xassert (it->sp > 0); 5380 xassert (it->sp > 0);
5109 --it->sp; 5381 --it->sp;
@@ -5131,22 +5403,10 @@ pop_it (struct it *it)
5131 it->object = p->u.xwidget.object; 5403 it->object = p->u.xwidget.object;
5132 break; 5404 break;
5133 case GET_FROM_STRETCH: 5405 case GET_FROM_STRETCH:
5134 it->object = p->u.comp.object; 5406 it->object = p->u.stretch.object;
5135 break; 5407 break;
5136 case GET_FROM_BUFFER: 5408 case GET_FROM_BUFFER:
5137 it->object = it->w->buffer; 5409 it->object = it->w->buffer;
5138 if (it->bidi_p)
5139 {
5140 /* Bidi-iterate until we get out of the portion of text, if
5141 any, covered by a `display' text property or an overlay
5142 with `display' property. (We cannot just jump there,
5143 because the internal coherency of the bidi iterator state
5144 can not be preserved across such jumps.) We also must
5145 determine the paragraph base direction if the overlay we
5146 just processed is at the beginning of a new
5147 paragraph. */
5148 iterate_out_of_display_property (it);
5149 }
5150 break; 5410 break;
5151 case GET_FROM_STRING: 5411 case GET_FROM_STRING:
5152 it->object = it->string; 5412 it->object = it->string;
@@ -5172,6 +5432,30 @@ pop_it (struct it *it)
5172 it->voffset = p->voffset; 5432 it->voffset = p->voffset;
5173 it->string_from_display_prop_p = p->string_from_display_prop_p; 5433 it->string_from_display_prop_p = p->string_from_display_prop_p;
5174 it->line_wrap = p->line_wrap; 5434 it->line_wrap = p->line_wrap;
5435 it->bidi_p = p->bidi_p;
5436 it->paragraph_embedding = p->paragraph_embedding;
5437 it->from_disp_prop_p = p->from_disp_prop_p;
5438 if (it->bidi_p)
5439 {
5440 bidi_pop_it (&it->bidi_it);
5441 /* Bidi-iterate until we get out of the portion of text, if any,
5442 covered by a `display' text property or by an overlay with
5443 `display' property. (We cannot just jump there, because the
5444 internal coherency of the bidi iterator state can not be
5445 preserved across such jumps.) We also must determine the
5446 paragraph base direction if the overlay we just processed is
5447 at the beginning of a new paragraph. */
5448 if (from_display_prop
5449 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5450 iterate_out_of_display_property (it);
5451
5452 xassert ((BUFFERP (it->object)
5453 && IT_CHARPOS (*it) == it->bidi_it.charpos
5454 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5455 || (STRINGP (it->object)
5456 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5457 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos));
5458 }
5175} 5459}
5176 5460
5177 5461
@@ -5255,15 +5539,16 @@ forward_to_next_line_start (struct it *it, int *skipped_p)
5255 5539
5256 xassert (!STRINGP (it->string)); 5540 xassert (!STRINGP (it->string));
5257 5541
5258 /* If there isn't any `display' property in sight, and no 5542 /* If we are not bidi-reordering, and there isn't any `display'
5259 overlays, we can just use the position of the newline in 5543 property in sight, and no overlays, we can just use the
5260 buffer text. */ 5544 position of the newline in buffer text. */
5261 if (it->stop_charpos >= limit 5545 if (!it->bidi_p
5262 || ((pos = Fnext_single_property_change (make_number (start), 5546 && (it->stop_charpos >= limit
5263 Qdisplay, 5547 || ((pos = Fnext_single_property_change (make_number (start),
5264 Qnil, make_number (limit)), 5548 Qdisplay, Qnil,
5265 NILP (pos)) 5549 make_number (limit)),
5266 && next_overlay_change (start) == ZV)) 5550 NILP (pos))
5551 && next_overlay_change (start) == ZV)))
5267 { 5552 {
5268 IT_CHARPOS (*it) = limit; 5553 IT_CHARPOS (*it) = limit;
5269 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit); 5554 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
@@ -5321,10 +5606,13 @@ back_to_previous_visible_line_start (struct it *it)
5321 5606
5322 { 5607 {
5323 struct it it2; 5608 struct it it2;
5609 void *it2data = NULL;
5324 EMACS_INT pos; 5610 EMACS_INT pos;
5325 EMACS_INT beg, end; 5611 EMACS_INT beg, end;
5326 Lisp_Object val, overlay; 5612 Lisp_Object val, overlay;
5327 5613
5614 SAVE_IT (it2, *it, it2data);
5615
5328 /* If newline is part of a composition, continue from start of composition */ 5616 /* If newline is part of a composition, continue from start of composition */
5329 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil) 5617 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5330 && beg < IT_CHARPOS (*it)) 5618 && beg < IT_CHARPOS (*it))
@@ -5332,20 +5620,25 @@ back_to_previous_visible_line_start (struct it *it)
5332 5620
5333 /* If newline is replaced by a display property, find start of overlay 5621 /* If newline is replaced by a display property, find start of overlay
5334 or interval and continue search from that point. */ 5622 or interval and continue search from that point. */
5335 it2 = *it;
5336 pos = --IT_CHARPOS (it2); 5623 pos = --IT_CHARPOS (it2);
5337 --IT_BYTEPOS (it2); 5624 --IT_BYTEPOS (it2);
5338 it2.sp = 0; 5625 it2.sp = 0;
5626 bidi_unshelve_cache (NULL);
5339 it2.string_from_display_prop_p = 0; 5627 it2.string_from_display_prop_p = 0;
5628 it2.from_disp_prop_p = 0;
5340 if (handle_display_prop (&it2) == HANDLED_RETURN 5629 if (handle_display_prop (&it2) == HANDLED_RETURN
5341 && !NILP (val = get_char_property_and_overlay 5630 && !NILP (val = get_char_property_and_overlay
5342 (make_number (pos), Qdisplay, Qnil, &overlay)) 5631 (make_number (pos), Qdisplay, Qnil, &overlay))
5343 && (OVERLAYP (overlay) 5632 && (OVERLAYP (overlay)
5344 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay))) 5633 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5345 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil))) 5634 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5346 goto replaced; 5635 {
5636 RESTORE_IT (it, it, it2data);
5637 goto replaced;
5638 }
5347 5639
5348 /* Newline is not replaced by anything -- so we are done. */ 5640 /* Newline is not replaced by anything -- so we are done. */
5641 RESTORE_IT (it, it, it2data);
5349 break; 5642 break;
5350 5643
5351 replaced: 5644 replaced:
@@ -5412,14 +5705,29 @@ reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5412 { 5705 {
5413 if (IT_STRING_CHARPOS (*it) > 0) 5706 if (IT_STRING_CHARPOS (*it) > 0)
5414 { 5707 {
5415 --IT_STRING_CHARPOS (*it); 5708 if (!it->bidi_p)
5416 --IT_STRING_BYTEPOS (*it); 5709 {
5710 --IT_STRING_CHARPOS (*it);
5711 --IT_STRING_BYTEPOS (*it);
5712 }
5713 else
5714 /* Setting this flag will cause
5715 bidi_move_to_visually_next not to advance, but
5716 instead deliver the current character (newline),
5717 which is what the ON_NEWLINE_P flag wants. */
5718 it->bidi_it.first_elt = 1;
5417 } 5719 }
5418 } 5720 }
5419 else if (IT_CHARPOS (*it) > BEGV) 5721 else if (IT_CHARPOS (*it) > BEGV)
5420 { 5722 {
5421 --IT_CHARPOS (*it); 5723 if (!it->bidi_p)
5422 --IT_BYTEPOS (*it); 5724 {
5725 --IT_CHARPOS (*it);
5726 --IT_BYTEPOS (*it);
5727 }
5728 /* With bidi iteration, the call to `reseat' will cause
5729 bidi_move_to_visually_next deliver the current character,
5730 the newline, instead of advancing. */
5423 reseat (it, it->current.pos, 0); 5731 reseat (it, it->current.pos, 0);
5424 } 5732 }
5425 } 5733 }
@@ -5501,19 +5809,24 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5501 IT_STRING_CHARPOS (*it) = -1; 5809 IT_STRING_CHARPOS (*it) = -1;
5502 IT_STRING_BYTEPOS (*it) = -1; 5810 IT_STRING_BYTEPOS (*it) = -1;
5503 it->string = Qnil; 5811 it->string = Qnil;
5504 it->string_from_display_prop_p = 0;
5505 it->method = GET_FROM_BUFFER; 5812 it->method = GET_FROM_BUFFER;
5506 it->object = it->w->buffer; 5813 it->object = it->w->buffer;
5507 it->area = TEXT_AREA; 5814 it->area = TEXT_AREA;
5508 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters)); 5815 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
5509 it->sp = 0; 5816 it->sp = 0;
5510 it->string_from_display_prop_p = 0; 5817 it->string_from_display_prop_p = 0;
5818 it->from_disp_prop_p = 0;
5511 it->face_before_selective_p = 0; 5819 it->face_before_selective_p = 0;
5512 if (it->bidi_p) 5820 if (it->bidi_p)
5513 { 5821 {
5514 it->bidi_it.first_elt = 1; 5822 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5823 &it->bidi_it);
5824 bidi_unshelve_cache (NULL);
5515 it->bidi_it.paragraph_dir = NEUTRAL_DIR; 5825 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5516 it->bidi_it.disp_pos = -1; 5826 it->bidi_it.string.s = NULL;
5827 it->bidi_it.string.lstring = Qnil;
5828 it->bidi_it.string.bufpos = 0;
5829 it->bidi_it.string.unibyte = 0;
5517 } 5830 }
5518 5831
5519 if (set_stop_p) 5832 if (set_stop_p)
@@ -5564,6 +5877,10 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5564 if (multibyte >= 0) 5877 if (multibyte >= 0)
5565 it->multibyte_p = multibyte > 0; 5878 it->multibyte_p = multibyte > 0;
5566 5879
5880 /* Bidirectional reordering of strings is controlled by the default
5881 value of bidi-display-reordering. */
5882 it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
5883
5567 if (s == NULL) 5884 if (s == NULL)
5568 { 5885 {
5569 xassert (STRINGP (string)); 5886 xassert (STRINGP (string));
@@ -5572,6 +5889,18 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5572 it->end_charpos = it->string_nchars = SCHARS (string); 5889 it->end_charpos = it->string_nchars = SCHARS (string);
5573 it->method = GET_FROM_STRING; 5890 it->method = GET_FROM_STRING;
5574 it->current.string_pos = string_pos (charpos, string); 5891 it->current.string_pos = string_pos (charpos, string);
5892
5893 if (it->bidi_p)
5894 {
5895 it->bidi_it.string.lstring = string;
5896 it->bidi_it.string.s = NULL;
5897 it->bidi_it.string.schars = it->end_charpos;
5898 it->bidi_it.string.bufpos = 0;
5899 it->bidi_it.string.from_disp_str = 0;
5900 it->bidi_it.string.unibyte = !it->multibyte_p;
5901 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
5902 FRAME_WINDOW_P (it->f), &it->bidi_it);
5903 }
5575 } 5904 }
5576 else 5905 else
5577 { 5906 {
@@ -5592,13 +5921,28 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5592 it->end_charpos = it->string_nchars = strlen (s); 5921 it->end_charpos = it->string_nchars = strlen (s);
5593 } 5922 }
5594 5923
5924 if (it->bidi_p)
5925 {
5926 it->bidi_it.string.lstring = Qnil;
5927 it->bidi_it.string.s = (const unsigned char *) s;
5928 it->bidi_it.string.schars = it->end_charpos;
5929 it->bidi_it.string.bufpos = 0;
5930 it->bidi_it.string.from_disp_str = 0;
5931 it->bidi_it.string.unibyte = !it->multibyte_p;
5932 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5933 &it->bidi_it);
5934 }
5595 it->method = GET_FROM_C_STRING; 5935 it->method = GET_FROM_C_STRING;
5596 } 5936 }
5597 5937
5598 /* PRECISION > 0 means don't return more than PRECISION characters 5938 /* PRECISION > 0 means don't return more than PRECISION characters
5599 from the string. */ 5939 from the string. */
5600 if (precision > 0 && it->end_charpos - charpos > precision) 5940 if (precision > 0 && it->end_charpos - charpos > precision)
5601 it->end_charpos = it->string_nchars = charpos + precision; 5941 {
5942 it->end_charpos = it->string_nchars = charpos + precision;
5943 if (it->bidi_p)
5944 it->bidi_it.string.schars = it->end_charpos;
5945 }
5602 5946
5603 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH 5947 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5604 characters have been returned. FIELD_WIDTH == 0 means don't pad, 5948 characters have been returned. FIELD_WIDTH == 0 means don't pad,
@@ -5606,6 +5950,9 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5606 padding with `-' at the end of a mode line. */ 5950 padding with `-' at the end of a mode line. */
5607 if (field_width < 0) 5951 if (field_width < 0)
5608 field_width = INFINITY; 5952 field_width = INFINITY;
5953 /* Implementation note: We deliberately don't enlarge
5954 it->bidi_it.string.schars here to fit it->end_charpos, because
5955 the bidi iterator cannot produce characters out of thin air. */
5609 if (field_width > it->end_charpos - charpos) 5956 if (field_width > it->end_charpos - charpos)
5610 it->end_charpos = charpos + field_width; 5957 it->end_charpos = charpos + field_width;
5611 5958
@@ -5614,6 +5961,14 @@ reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5614 it->dp = XCHAR_TABLE (Vstandard_display_table); 5961 it->dp = XCHAR_TABLE (Vstandard_display_table);
5615 5962
5616 it->stop_charpos = charpos; 5963 it->stop_charpos = charpos;
5964 it->prev_stop = charpos;
5965 it->base_level_stop = 0;
5966 if (it->bidi_p)
5967 {
5968 it->bidi_it.first_elt = 1;
5969 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5970 it->bidi_it.disp_pos = -1;
5971 }
5617 if (s == NULL && it->multibyte_p) 5972 if (s == NULL && it->multibyte_p)
5618 { 5973 {
5619 EMACS_INT endpos = SCHARS (it->string); 5974 EMACS_INT endpos = SCHARS (it->string);
@@ -6249,8 +6604,22 @@ set_iterator_to_next (struct it *it, int reseat_p)
6249 6604
6250 case GET_FROM_C_STRING: 6605 case GET_FROM_C_STRING:
6251 /* Current display element of IT is from a C string. */ 6606 /* Current display element of IT is from a C string. */
6252 IT_BYTEPOS (*it) += it->len; 6607 if (!it->bidi_p
6253 IT_CHARPOS (*it) += 1; 6608 /* If the string position is beyond string's end, it means
6609 next_element_from_c_string is padding the string with
6610 blanks, in which case we bypass the bidi iterator,
6611 because it cannot deal with such virtual characters. */
6612 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
6613 {
6614 IT_BYTEPOS (*it) += it->len;
6615 IT_CHARPOS (*it) += 1;
6616 }
6617 else
6618 {
6619 bidi_move_to_visually_next (&it->bidi_it);
6620 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6621 IT_CHARPOS (*it) = it->bidi_it.charpos;
6622 }
6254 break; 6623 break;
6255 6624
6256 case GET_FROM_DISPLAY_VECTOR: 6625 case GET_FROM_DISPLAY_VECTOR:
@@ -6304,23 +6673,95 @@ set_iterator_to_next (struct it *it, int reseat_p)
6304 xassert (it->s == NULL && STRINGP (it->string)); 6673 xassert (it->s == NULL && STRINGP (it->string));
6305 if (it->cmp_it.id >= 0) 6674 if (it->cmp_it.id >= 0)
6306 { 6675 {
6307 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars; 6676 int i;
6308 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes; 6677
6309 if (it->cmp_it.to < it->cmp_it.nglyphs) 6678 if (! it->bidi_p)
6310 it->cmp_it.from = it->cmp_it.to; 6679 {
6680 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6681 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6682 if (it->cmp_it.to < it->cmp_it.nglyphs)
6683 it->cmp_it.from = it->cmp_it.to;
6684 else
6685 {
6686 it->cmp_it.id = -1;
6687 composition_compute_stop_pos (&it->cmp_it,
6688 IT_STRING_CHARPOS (*it),
6689 IT_STRING_BYTEPOS (*it),
6690 it->end_charpos, it->string);
6691 }
6692 }
6693 else if (! it->cmp_it.reversed_p)
6694 {
6695 for (i = 0; i < it->cmp_it.nchars; i++)
6696 bidi_move_to_visually_next (&it->bidi_it);
6697 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6698 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6699
6700 if (it->cmp_it.to < it->cmp_it.nglyphs)
6701 it->cmp_it.from = it->cmp_it.to;
6702 else
6703 {
6704 EMACS_INT stop = it->end_charpos;
6705 if (it->bidi_it.scan_dir < 0)
6706 stop = -1;
6707 composition_compute_stop_pos (&it->cmp_it,
6708 IT_STRING_CHARPOS (*it),
6709 IT_STRING_BYTEPOS (*it), stop,
6710 it->string);
6711 }
6712 }
6311 else 6713 else
6312 { 6714 {
6313 it->cmp_it.id = -1; 6715 for (i = 0; i < it->cmp_it.nchars; i++)
6314 composition_compute_stop_pos (&it->cmp_it, 6716 bidi_move_to_visually_next (&it->bidi_it);
6315 IT_STRING_CHARPOS (*it), 6717 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6316 IT_STRING_BYTEPOS (*it), 6718 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6317 it->end_charpos, it->string); 6719 if (it->cmp_it.from > 0)
6720 it->cmp_it.to = it->cmp_it.from;
6721 else
6722 {
6723 EMACS_INT stop = it->end_charpos;
6724 if (it->bidi_it.scan_dir < 0)
6725 stop = -1;
6726 composition_compute_stop_pos (&it->cmp_it,
6727 IT_STRING_CHARPOS (*it),
6728 IT_STRING_BYTEPOS (*it), stop,
6729 it->string);
6730 }
6318 } 6731 }
6319 } 6732 }
6320 else 6733 else
6321 { 6734 {
6322 IT_STRING_BYTEPOS (*it) += it->len; 6735 if (!it->bidi_p
6323 IT_STRING_CHARPOS (*it) += 1; 6736 /* If the string position is beyond string's end, it
6737 means next_element_from_string is padding the string
6738 with blanks, in which case we bypass the bidi
6739 iterator, because it cannot deal with such virtual
6740 characters. */
6741 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
6742 {
6743 IT_STRING_BYTEPOS (*it) += it->len;
6744 IT_STRING_CHARPOS (*it) += 1;
6745 }
6746 else
6747 {
6748 int prev_scan_dir = it->bidi_it.scan_dir;
6749
6750 bidi_move_to_visually_next (&it->bidi_it);
6751 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6752 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6753 if (prev_scan_dir != it->bidi_it.scan_dir)
6754 {
6755 EMACS_INT stop = it->end_charpos;
6756
6757 if (it->bidi_it.scan_dir < 0)
6758 stop = -1;
6759 composition_compute_stop_pos (&it->cmp_it,
6760 IT_STRING_CHARPOS (*it),
6761 IT_STRING_BYTEPOS (*it), stop,
6762 it->string);
6763 }
6764 }
6324 } 6765 }
6325 6766
6326 consider_string_end: 6767 consider_string_end:
@@ -6427,6 +6868,107 @@ next_element_from_display_vector (struct it *it)
6427 return 1; 6868 return 1;
6428} 6869}
6429 6870
6871/* Get the first element of string/buffer in the visual order, after
6872 being reseated to a new position in a string or a buffer. */
6873static void
6874get_visually_first_element (struct it *it)
6875{
6876 int string_p = STRINGP (it->string) || it->s;
6877 EMACS_INT eob = (string_p ? it->bidi_it.string.schars : ZV);
6878 EMACS_INT bob = (string_p ? 0 : BEGV);
6879
6880 if (STRINGP (it->string))
6881 {
6882 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
6883 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
6884 }
6885 else
6886 {
6887 it->bidi_it.charpos = IT_CHARPOS (*it);
6888 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6889 }
6890
6891 if (it->bidi_it.charpos == eob)
6892 {
6893 /* Nothing to do, but reset the FIRST_ELT flag, like
6894 bidi_paragraph_init does, because we are not going to
6895 call it. */
6896 it->bidi_it.first_elt = 0;
6897 }
6898 else if (it->bidi_it.charpos == bob
6899 || (!string_p
6900 /* FIXME: Should support all Unicode line separators. */
6901 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6902 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
6903 {
6904 /* If we are at the beginning of a line/string, we can produce
6905 the next element right away. */
6906 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6907 bidi_move_to_visually_next (&it->bidi_it);
6908 }
6909 else
6910 {
6911 EMACS_INT orig_bytepos = it->bidi_it.bytepos;
6912
6913 /* We need to prime the bidi iterator starting at the line's or
6914 string's beginning, before we will be able to produce the
6915 next element. */
6916 if (string_p)
6917 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
6918 else
6919 {
6920 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
6921 -1);
6922 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
6923 }
6924 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6925 do
6926 {
6927 /* Now return to buffer/string position where we were asked
6928 to get the next display element, and produce that. */
6929 bidi_move_to_visually_next (&it->bidi_it);
6930 }
6931 while (it->bidi_it.bytepos != orig_bytepos
6932 && it->bidi_it.charpos < eob);
6933 }
6934
6935 /* Adjust IT's position information to where we ended up. */
6936 if (STRINGP (it->string))
6937 {
6938 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6939 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6940 }
6941 else
6942 {
6943 IT_CHARPOS (*it) = it->bidi_it.charpos;
6944 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6945 }
6946
6947 if (STRINGP (it->string) || !it->s)
6948 {
6949 EMACS_INT stop, charpos, bytepos;
6950
6951 if (STRINGP (it->string))
6952 {
6953 xassert (!it->s);
6954 stop = SCHARS (it->string);
6955 if (stop > it->end_charpos)
6956 stop = it->end_charpos;
6957 charpos = IT_STRING_CHARPOS (*it);
6958 bytepos = IT_STRING_BYTEPOS (*it);
6959 }
6960 else
6961 {
6962 stop = it->end_charpos;
6963 charpos = IT_CHARPOS (*it);
6964 bytepos = IT_BYTEPOS (*it);
6965 }
6966 if (it->bidi_it.scan_dir < 0)
6967 stop = -1;
6968 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
6969 it->string);
6970 }
6971}
6430 6972
6431/* Load IT with the next display element from Lisp string IT->string. 6973/* Load IT with the next display element from Lisp string IT->string.
6432 IT->current.string_pos is the current position within the string. 6974 IT->current.string_pos is the current position within the string.
@@ -6439,18 +6981,79 @@ next_element_from_string (struct it *it)
6439 struct text_pos position; 6981 struct text_pos position;
6440 6982
6441 xassert (STRINGP (it->string)); 6983 xassert (STRINGP (it->string));
6984 xassert (!it->bidi_p || it->string == it->bidi_it.string.lstring);
6442 xassert (IT_STRING_CHARPOS (*it) >= 0); 6985 xassert (IT_STRING_CHARPOS (*it) >= 0);
6443 position = it->current.string_pos; 6986 position = it->current.string_pos;
6444 6987
6988 /* With bidi reordering, the character to display might not be the
6989 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
6990 that we were reseat()ed to a new string, whose paragraph
6991 direction is not known. */
6992 if (it->bidi_p && it->bidi_it.first_elt)
6993 {
6994 get_visually_first_element (it);
6995 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
6996 }
6997
6445 /* Time to check for invisible text? */ 6998 /* Time to check for invisible text? */
6446 if (IT_STRING_CHARPOS (*it) < it->end_charpos 6999 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
6447 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6448 { 7000 {
6449 handle_stop (it); 7001 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7002 {
7003 if (!(!it->bidi_p
7004 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7005 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7006 {
7007 /* With bidi non-linear iteration, we could find
7008 ourselves far beyond the last computed stop_charpos,
7009 with several other stop positions in between that we
7010 missed. Scan them all now, in buffer's logical
7011 order, until we find and handle the last stop_charpos
7012 that precedes our current position. */
7013 handle_stop_backwards (it, it->stop_charpos);
7014 return GET_NEXT_DISPLAY_ELEMENT (it);
7015 }
7016 else
7017 {
7018 if (it->bidi_p)
7019 {
7020 /* Take note of the stop position we just moved
7021 across, for when we will move back across it. */
7022 it->prev_stop = it->stop_charpos;
7023 /* If we are at base paragraph embedding level, take
7024 note of the last stop position seen at this
7025 level. */
7026 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7027 it->base_level_stop = it->stop_charpos;
7028 }
7029 handle_stop (it);
6450 7030
6451 /* Since a handler may have changed IT->method, we must 7031 /* Since a handler may have changed IT->method, we must
6452 recurse here. */ 7032 recurse here. */
6453 return GET_NEXT_DISPLAY_ELEMENT (it); 7033 return GET_NEXT_DISPLAY_ELEMENT (it);
7034 }
7035 }
7036 else if (it->bidi_p
7037 /* If we are before prev_stop, we may have overstepped
7038 on our way backwards a stop_pos, and if so, we need
7039 to handle that stop_pos. */
7040 && IT_STRING_CHARPOS (*it) < it->prev_stop
7041 /* We can sometimes back up for reasons that have nothing
7042 to do with bidi reordering. E.g., compositions. The
7043 code below is only needed when we are above the base
7044 embedding level, so test for that explicitly. */
7045 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7046 {
7047 /* If we lost track of base_level_stop, we have no better place
7048 for handle_stop_backwards to start from than BEGV. This
7049 happens, e.g., when we were reseated to the previous
7050 screenful of text by vertical-motion. */
7051 if (it->base_level_stop <= 0
7052 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7053 it->base_level_stop = 0;
7054 handle_stop_backwards (it, it->base_level_stop);
7055 return GET_NEXT_DISPLAY_ELEMENT (it);
7056 }
6454 } 7057 }
6455 7058
6456 if (it->current.overlay_string_index >= 0) 7059 if (it->current.overlay_string_index >= 0)
@@ -6464,7 +7067,10 @@ next_element_from_string (struct it *it)
6464 return 0; 7067 return 0;
6465 } 7068 }
6466 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it), 7069 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6467 IT_STRING_BYTEPOS (*it), SCHARS (it->string)) 7070 IT_STRING_BYTEPOS (*it),
7071 it->bidi_it.scan_dir < 0
7072 ? -1
7073 : SCHARS (it->string))
6468 && next_element_from_composition (it)) 7074 && next_element_from_composition (it))
6469 { 7075 {
6470 return 1; 7076 return 1;
@@ -6499,7 +7105,10 @@ next_element_from_string (struct it *it)
6499 CHARPOS (position) = BYTEPOS (position) = -1; 7105 CHARPOS (position) = BYTEPOS (position) = -1;
6500 } 7106 }
6501 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it), 7107 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6502 IT_STRING_BYTEPOS (*it), it->string_nchars) 7108 IT_STRING_BYTEPOS (*it),
7109 it->bidi_it.scan_dir < 0
7110 ? -1
7111 : it->string_nchars)
6503 && next_element_from_composition (it)) 7112 && next_element_from_composition (it))
6504 { 7113 {
6505 return 1; 7114 return 1;
@@ -6538,12 +7147,20 @@ next_element_from_c_string (struct it *it)
6538 int success_p = 1; 7147 int success_p = 1;
6539 7148
6540 xassert (it->s); 7149 xassert (it->s);
7150 xassert (!it->bidi_p || it->s == it->bidi_it.string.s);
6541 it->what = IT_CHARACTER; 7151 it->what = IT_CHARACTER;
6542 BYTEPOS (it->position) = CHARPOS (it->position) = 0; 7152 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6543 it->object = Qnil; 7153 it->object = Qnil;
6544 7154
6545 /* IT's position can be greater IT->string_nchars in case a field 7155 /* With bidi reordering, the character to display might not be the
6546 width or precision has been specified when the iterator was 7156 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7157 we were reseated to a new string, whose paragraph direction is
7158 not known. */
7159 if (it->bidi_p && it->bidi_it.first_elt)
7160 get_visually_first_element (it);
7161
7162 /* IT's position can be greater than IT->string_nchars in case a
7163 field width or precision has been specified when the iterator was
6547 initialized. */ 7164 initialized. */
6548 if (IT_CHARPOS (*it) >= it->end_charpos) 7165 if (IT_CHARPOS (*it) >= it->end_charpos)
6549 { 7166 {
@@ -6630,18 +7247,19 @@ next_element_from_stretch (struct it *it)
6630 return 1; 7247 return 1;
6631} 7248}
6632 7249
6633/* Scan forward from CHARPOS in the current buffer, until we find a 7250/* Scan forward from CHARPOS in the current buffer/string, until we
6634 stop position > current IT's position. Then handle the stop 7251 find a stop position > current IT's position. Then handle the stop
6635 position before that. This is called when we bump into a stop 7252 position before that. This is called when we bump into a stop
6636 position while reordering bidirectional text. CHARPOS should be 7253 position while reordering bidirectional text. CHARPOS should be
6637 the last previously processed stop_pos (or BEGV, if none were 7254 the last previously processed stop_pos (or BEGV/0, if none were
6638 processed yet) whose position is less that IT's current 7255 processed yet) whose position is less that IT's current
6639 position. */ 7256 position. */
6640 7257
6641static void 7258static void
6642handle_stop_backwards (struct it *it, EMACS_INT charpos) 7259handle_stop_backwards (struct it *it, EMACS_INT charpos)
6643{ 7260{
6644 EMACS_INT where_we_are = IT_CHARPOS (*it); 7261 int bufp = !STRINGP (it->string);
7262 EMACS_INT where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
6645 struct display_pos save_current = it->current; 7263 struct display_pos save_current = it->current;
6646 struct text_pos save_position = it->position; 7264 struct text_pos save_position = it->position;
6647 struct text_pos pos1; 7265 struct text_pos pos1;
@@ -6652,8 +7270,13 @@ handle_stop_backwards (struct it *it, EMACS_INT charpos)
6652 do 7270 do
6653 { 7271 {
6654 it->prev_stop = charpos; 7272 it->prev_stop = charpos;
6655 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos)); 7273 if (bufp)
6656 reseat_1 (it, pos1, 0); 7274 {
7275 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7276 reseat_1 (it, pos1, 0);
7277 }
7278 else
7279 it->current.string_pos = string_pos (charpos, it->string);
6657 compute_stop_pos (it); 7280 compute_stop_pos (it);
6658 /* We must advance forward, right? */ 7281 /* We must advance forward, right? */
6659 if (it->stop_charpos <= it->prev_stop) 7282 if (it->stop_charpos <= it->prev_stop)
@@ -6682,6 +7305,10 @@ next_element_from_buffer (struct it *it)
6682 int success_p = 1; 7305 int success_p = 1;
6683 7306
6684 xassert (IT_CHARPOS (*it) >= BEGV); 7307 xassert (IT_CHARPOS (*it) >= BEGV);
7308 xassert (NILP (it->string) && !it->s);
7309 xassert (!it->bidi_p
7310 || (it->bidi_it.string.lstring == Qnil
7311 && it->bidi_it.string.s == NULL));
6685 7312
6686 /* With bidi reordering, the character to display might not be the 7313 /* With bidi reordering, the character to display might not be the
6687 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that 7314 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
@@ -6689,59 +7316,8 @@ next_element_from_buffer (struct it *it)
6689 a different paragraph. */ 7316 a different paragraph. */
6690 if (it->bidi_p && it->bidi_it.first_elt) 7317 if (it->bidi_p && it->bidi_it.first_elt)
6691 { 7318 {
6692 it->bidi_it.charpos = IT_CHARPOS (*it); 7319 get_visually_first_element (it);
6693 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6694 if (it->bidi_it.bytepos == ZV_BYTE)
6695 {
6696 /* Nothing to do, but reset the FIRST_ELT flag, like
6697 bidi_paragraph_init does, because we are not going to
6698 call it. */
6699 it->bidi_it.first_elt = 0;
6700 }
6701 else if (it->bidi_it.bytepos == BEGV_BYTE
6702 /* FIXME: Should support all Unicode line separators. */
6703 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6704 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6705 {
6706 /* If we are at the beginning of a line, we can produce the
6707 next element right away. */
6708 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6709 bidi_move_to_visually_next (&it->bidi_it);
6710 }
6711 else
6712 {
6713 EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
6714
6715 /* We need to prime the bidi iterator starting at the line's
6716 beginning, before we will be able to produce the next
6717 element. */
6718 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6719 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6720 it->bidi_it.charpos = IT_CHARPOS (*it);
6721 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6722 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6723 do
6724 {
6725 /* Now return to buffer position where we were asked to
6726 get the next display element, and produce that. */
6727 bidi_move_to_visually_next (&it->bidi_it);
6728 }
6729 while (it->bidi_it.bytepos != orig_bytepos
6730 && it->bidi_it.bytepos < ZV_BYTE);
6731 }
6732
6733 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6734 /* Adjust IT's position information to where we ended up. */
6735 IT_CHARPOS (*it) = it->bidi_it.charpos;
6736 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6737 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it)); 7320 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6738 {
6739 EMACS_INT stop = it->end_charpos;
6740 if (it->bidi_it.scan_dir < 0)
6741 stop = -1;
6742 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6743 IT_BYTEPOS (*it), stop, Qnil);
6744 }
6745 } 7321 }
6746 7322
6747 if (IT_CHARPOS (*it) >= it->stop_charpos) 7323 if (IT_CHARPOS (*it) >= it->stop_charpos)
@@ -6800,17 +7376,23 @@ next_element_from_buffer (struct it *it)
6800 } 7376 }
6801 } 7377 }
6802 else if (it->bidi_p 7378 else if (it->bidi_p
7379 /* If we are before prev_stop, we may have overstepped on
7380 our way backwards a stop_pos, and if so, we need to
7381 handle that stop_pos. */
7382 && IT_CHARPOS (*it) < it->prev_stop
6803 /* We can sometimes back up for reasons that have nothing 7383 /* We can sometimes back up for reasons that have nothing
6804 to do with bidi reordering. E.g., compositions. The 7384 to do with bidi reordering. E.g., compositions. The
6805 code below is only needed when we are above the base 7385 code below is only needed when we are above the base
6806 embedding level, so test for that explicitly. */ 7386 embedding level, so test for that explicitly. */
6807 && !BIDI_AT_BASE_LEVEL (it->bidi_it) 7387 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
6808 && IT_CHARPOS (*it) < it->prev_stop) 7388 {
6809 { 7389 /* If we lost track of base_level_stop, we have no better place
6810 if (it->base_level_stop <= 0) 7390 for handle_stop_backwards to start from than BEGV. This
7391 happens, e.g., when we were reseated to the previous
7392 screenful of text by vertical-motion. */
7393 if (it->base_level_stop <= 0
7394 || IT_CHARPOS (*it) < it->base_level_stop)
6811 it->base_level_stop = BEGV; 7395 it->base_level_stop = BEGV;
6812 if (IT_CHARPOS (*it) < it->base_level_stop)
6813 abort ();
6814 handle_stop_backwards (it, it->base_level_stop); 7396 handle_stop_backwards (it, it->base_level_stop);
6815 return GET_NEXT_DISPLAY_ELEMENT (it); 7397 return GET_NEXT_DISPLAY_ELEMENT (it);
6816 } 7398 }
@@ -7014,9 +7596,11 @@ move_it_in_display_line_to (struct it *it,
7014 enum move_it_result result = MOVE_UNDEFINED; 7596 enum move_it_result result = MOVE_UNDEFINED;
7015 struct glyph_row *saved_glyph_row; 7597 struct glyph_row *saved_glyph_row;
7016 struct it wrap_it, atpos_it, atx_it; 7598 struct it wrap_it, atpos_it, atx_it;
7599 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
7017 int may_wrap = 0; 7600 int may_wrap = 0;
7018 enum it_method prev_method = it->method; 7601 enum it_method prev_method = it->method;
7019 EMACS_INT prev_pos = IT_CHARPOS (*it); 7602 EMACS_INT prev_pos = IT_CHARPOS (*it);
7603 int saw_smaller_pos = prev_pos < to_charpos;
7020 7604
7021 /* Don't produce glyphs in produce_glyphs. */ 7605 /* Don't produce glyphs in produce_glyphs. */
7022 saved_glyph_row = it->glyph_row; 7606 saved_glyph_row = it->glyph_row;
@@ -7057,15 +7641,16 @@ move_it_in_display_line_to (struct it *it,
7057 ((IT)->current_x = x, (IT)->max_ascent = ascent, \ 7641 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7058 (IT)->max_descent = descent) 7642 (IT)->max_descent = descent)
7059 7643
7060 /* Stop if we move beyond TO_CHARPOS (after an image or stretch 7644 /* Stop if we move beyond TO_CHARPOS (after an image or a
7061 glyph). */ 7645 display string or stretch glyph). */
7062 if ((op & MOVE_TO_POS) != 0 7646 if ((op & MOVE_TO_POS) != 0
7063 && BUFFERP (it->object) 7647 && BUFFERP (it->object)
7064 && it->method == GET_FROM_BUFFER 7648 && it->method == GET_FROM_BUFFER
7065 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos) 7649 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7066 || (it->bidi_p 7650 || (it->bidi_p
7067 && (prev_method == GET_FROM_IMAGE 7651 && (prev_method == GET_FROM_IMAGE
7068 || prev_method == GET_FROM_STRETCH) 7652 || prev_method == GET_FROM_STRETCH
7653 || prev_method == GET_FROM_STRING)
7069 /* Passed TO_CHARPOS from left to right. */ 7654 /* Passed TO_CHARPOS from left to right. */
7070 && ((prev_pos < to_charpos 7655 && ((prev_pos < to_charpos
7071 && IT_CHARPOS (*it) > to_charpos) 7656 && IT_CHARPOS (*it) > to_charpos)
@@ -7082,12 +7667,9 @@ move_it_in_display_line_to (struct it *it,
7082 /* If wrap_it is valid, the current position might be in a 7667 /* If wrap_it is valid, the current position might be in a
7083 word that is wrapped. So, save the iterator in 7668 word that is wrapped. So, save the iterator in
7084 atpos_it and continue to see if wrapping happens. */ 7669 atpos_it and continue to see if wrapping happens. */
7085 atpos_it = *it; 7670 SAVE_IT (atpos_it, *it, atpos_data);
7086 } 7671 }
7087 7672
7088 prev_method = it->method;
7089 if (it->method == GET_FROM_BUFFER)
7090 prev_pos = IT_CHARPOS (*it);
7091 /* Stop when ZV reached. 7673 /* Stop when ZV reached.
7092 We used to stop here when TO_CHARPOS reached as well, but that is 7674 We used to stop here when TO_CHARPOS reached as well, but that is
7093 too soon if this glyph does not fit on this line. So we handle it 7675 too soon if this glyph does not fit on this line. So we handle it
@@ -7119,18 +7701,18 @@ move_it_in_display_line_to (struct it *it,
7119 already found, we are done. */ 7701 already found, we are done. */
7120 if (atpos_it.sp >= 0) 7702 if (atpos_it.sp >= 0)
7121 { 7703 {
7122 *it = atpos_it; 7704 RESTORE_IT (it, &atpos_it, atpos_data);
7123 result = MOVE_POS_MATCH_OR_ZV; 7705 result = MOVE_POS_MATCH_OR_ZV;
7124 goto done; 7706 goto done;
7125 } 7707 }
7126 if (atx_it.sp >= 0) 7708 if (atx_it.sp >= 0)
7127 { 7709 {
7128 *it = atx_it; 7710 RESTORE_IT (it, &atx_it, atx_data);
7129 result = MOVE_X_REACHED; 7711 result = MOVE_X_REACHED;
7130 goto done; 7712 goto done;
7131 } 7713 }
7132 /* Otherwise, we can wrap here. */ 7714 /* Otherwise, we can wrap here. */
7133 wrap_it = *it; 7715 SAVE_IT (wrap_it, *it, wrap_data);
7134 may_wrap = 0; 7716 may_wrap = 0;
7135 } 7717 }
7136 } 7718 }
@@ -7151,6 +7733,9 @@ move_it_in_display_line_to (struct it *it,
7151 7733
7152 if (it->area != TEXT_AREA) 7734 if (it->area != TEXT_AREA)
7153 { 7735 {
7736 prev_method = it->method;
7737 if (it->method == GET_FROM_BUFFER)
7738 prev_pos = IT_CHARPOS (*it);
7154 set_iterator_to_next (it, 1); 7739 set_iterator_to_next (it, 1);
7155 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) 7740 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7156 SET_TEXT_POS (this_line_min_pos, 7741 SET_TEXT_POS (this_line_min_pos,
@@ -7198,7 +7783,7 @@ move_it_in_display_line_to (struct it *it,
7198 goto buffer_pos_reached; 7783 goto buffer_pos_reached;
7199 if (atpos_it.sp < 0) 7784 if (atpos_it.sp < 0)
7200 { 7785 {
7201 atpos_it = *it; 7786 SAVE_IT (atpos_it, *it, atpos_data);
7202 IT_RESET_X_ASCENT_DESCENT (&atpos_it); 7787 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7203 } 7788 }
7204 } 7789 }
@@ -7212,7 +7797,7 @@ move_it_in_display_line_to (struct it *it,
7212 } 7797 }
7213 if (atx_it.sp < 0) 7798 if (atx_it.sp < 0)
7214 { 7799 {
7215 atx_it = *it; 7800 SAVE_IT (atx_it, *it, atx_data);
7216 IT_RESET_X_ASCENT_DESCENT (&atx_it); 7801 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7217 } 7802 }
7218 } 7803 }
@@ -7256,12 +7841,15 @@ move_it_in_display_line_to (struct it *it,
7256 if (it->line_wrap == WORD_WRAP 7841 if (it->line_wrap == WORD_WRAP
7257 && atpos_it.sp < 0) 7842 && atpos_it.sp < 0)
7258 { 7843 {
7259 atpos_it = *it; 7844 SAVE_IT (atpos_it, *it, atpos_data);
7260 atpos_it.current_x = x_before_this_char; 7845 atpos_it.current_x = x_before_this_char;
7261 atpos_it.hpos = hpos_before_this_char; 7846 atpos_it.hpos = hpos_before_this_char;
7262 } 7847 }
7263 } 7848 }
7264 7849
7850 prev_method = it->method;
7851 if (it->method == GET_FROM_BUFFER)
7852 prev_pos = IT_CHARPOS (*it);
7265 set_iterator_to_next (it, 1); 7853 set_iterator_to_next (it, 1);
7266 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) 7854 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7267 SET_TEXT_POS (this_line_min_pos, 7855 SET_TEXT_POS (this_line_min_pos,
@@ -7301,7 +7889,7 @@ move_it_in_display_line_to (struct it *it,
7301 7889
7302 if (wrap_it.sp >= 0) 7890 if (wrap_it.sp >= 0)
7303 { 7891 {
7304 *it = wrap_it; 7892 RESTORE_IT (it, &wrap_it, wrap_data);
7305 atpos_it.sp = -1; 7893 atpos_it.sp = -1;
7306 atx_it.sp = -1; 7894 atx_it.sp = -1;
7307 } 7895 }
@@ -7318,7 +7906,7 @@ move_it_in_display_line_to (struct it *it,
7318 goto buffer_pos_reached; 7906 goto buffer_pos_reached;
7319 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0) 7907 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7320 { 7908 {
7321 atpos_it = *it; 7909 SAVE_IT (atpos_it, *it, atpos_data);
7322 IT_RESET_X_ASCENT_DESCENT (&atpos_it); 7910 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7323 } 7911 }
7324 } 7912 }
@@ -7355,10 +7943,20 @@ move_it_in_display_line_to (struct it *it,
7355 /* Is this a line end? If yes, we're done. */ 7943 /* Is this a line end? If yes, we're done. */
7356 if (ITERATOR_AT_END_OF_LINE_P (it)) 7944 if (ITERATOR_AT_END_OF_LINE_P (it))
7357 { 7945 {
7358 result = MOVE_NEWLINE_OR_CR; 7946 /* If we are past TO_CHARPOS, but never saw any character
7947 positions smaller than TO_CHARPOS, return
7948 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
7949 did. */
7950 if ((op & MOVE_TO_POS) != 0
7951 && !saw_smaller_pos
7952 && IT_CHARPOS (*it) > to_charpos)
7953 result = MOVE_POS_MATCH_OR_ZV;
7954 else
7955 result = MOVE_NEWLINE_OR_CR;
7359 break; 7956 break;
7360 } 7957 }
7361 7958
7959 prev_method = it->method;
7362 if (it->method == GET_FROM_BUFFER) 7960 if (it->method == GET_FROM_BUFFER)
7363 prev_pos = IT_CHARPOS (*it); 7961 prev_pos = IT_CHARPOS (*it);
7364 /* The current display element has been consumed. Advance 7962 /* The current display element has been consumed. Advance
@@ -7366,6 +7964,8 @@ move_it_in_display_line_to (struct it *it,
7366 set_iterator_to_next (it, 1); 7964 set_iterator_to_next (it, 1);
7367 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) 7965 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7368 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); 7966 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7967 if (IT_CHARPOS (*it) < to_charpos)
7968 saw_smaller_pos = 1;
7369 7969
7370 /* Stop if lines are truncated and IT's current x-position is 7970 /* Stop if lines are truncated and IT's current x-position is
7371 past the right edge of the window now. */ 7971 past the right edge of the window now. */
@@ -7398,12 +7998,19 @@ move_it_in_display_line_to (struct it *it,
7398 /* If we scanned beyond to_pos and didn't find a point to wrap at, 7998 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7399 restore the saved iterator. */ 7999 restore the saved iterator. */
7400 if (atpos_it.sp >= 0) 8000 if (atpos_it.sp >= 0)
7401 *it = atpos_it; 8001 RESTORE_IT (it, &atpos_it, atpos_data);
7402 else if (atx_it.sp >= 0) 8002 else if (atx_it.sp >= 0)
7403 *it = atx_it; 8003 RESTORE_IT (it, &atx_it, atx_data);
7404 8004
7405 done: 8005 done:
7406 8006
8007 if (atpos_data)
8008 xfree (atpos_data);
8009 if (atx_data)
8010 xfree (atx_data);
8011 if (wrap_data)
8012 xfree (wrap_data);
8013
7407 /* Restore the iterator settings altered at the beginning of this 8014 /* Restore the iterator settings altered at the beginning of this
7408 function. */ 8015 function. */
7409 it->glyph_row = saved_glyph_row; 8016 it->glyph_row = saved_glyph_row;
@@ -7419,8 +8026,12 @@ move_it_in_display_line (struct it *it,
7419 if (it->line_wrap == WORD_WRAP 8026 if (it->line_wrap == WORD_WRAP
7420 && (op & MOVE_TO_X)) 8027 && (op & MOVE_TO_X))
7421 { 8028 {
7422 struct it save_it = *it; 8029 struct it save_it;
7423 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op); 8030 void *save_data = NULL;
8031 int skip;
8032
8033 SAVE_IT (save_it, *it, save_data);
8034 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7424 /* When word-wrap is on, TO_X may lie past the end 8035 /* When word-wrap is on, TO_X may lie past the end
7425 of a wrapped line. Then it->current is the 8036 of a wrapped line. Then it->current is the
7426 character on the next line, so backtrack to the 8037 character on the next line, so backtrack to the
@@ -7428,10 +8039,12 @@ move_it_in_display_line (struct it *it,
7428 if (skip == MOVE_LINE_CONTINUED) 8039 if (skip == MOVE_LINE_CONTINUED)
7429 { 8040 {
7430 int prev_x = max (it->current_x - 1, 0); 8041 int prev_x = max (it->current_x - 1, 0);
7431 *it = save_it; 8042 RESTORE_IT (it, &save_it, save_data);
7432 move_it_in_display_line_to 8043 move_it_in_display_line_to
7433 (it, -1, prev_x, MOVE_TO_X); 8044 (it, -1, prev_x, MOVE_TO_X);
7434 } 8045 }
8046 else
8047 xfree (save_data);
7435 } 8048 }
7436 else 8049 else
7437 move_it_in_display_line_to (it, to_charpos, to_x, op); 8050 move_it_in_display_line_to (it, to_charpos, to_x, op);
@@ -7446,14 +8059,15 @@ move_it_in_display_line (struct it *it,
7446 description of enum move_operation_enum. 8059 description of enum move_operation_enum.
7447 8060
7448 If TO_CHARPOS is in invisible text, e.g. a truncated part of a 8061 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7449 screen line, this function will set IT to the next position > 8062 screen line, this function will set IT to the next position that is
7450 TO_CHARPOS. */ 8063 displayed to the right of TO_CHARPOS on the screen. */
7451 8064
7452void 8065void
7453move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op) 8066move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
7454{ 8067{
7455 enum move_it_result skip, skip2 = MOVE_X_REACHED; 8068 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7456 int line_height, line_start_x = 0, reached = 0; 8069 int line_height, line_start_x = 0, reached = 0;
8070 void *backup_data = NULL;
7457 8071
7458 for (;;) 8072 for (;;)
7459 { 8073 {
@@ -7506,7 +8120,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
7506 struct it it_backup; 8120 struct it it_backup;
7507 8121
7508 if (it->line_wrap == WORD_WRAP) 8122 if (it->line_wrap == WORD_WRAP)
7509 it_backup = *it; 8123 SAVE_IT (it_backup, *it, backup_data);
7510 8124
7511 /* TO_Y specified means stop at TO_X in the line containing 8125 /* TO_Y specified means stop at TO_X in the line containing
7512 TO_Y---or at TO_CHARPOS if this is reached first. The 8126 TO_Y---or at TO_CHARPOS if this is reached first. The
@@ -7540,7 +8154,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
7540 reached = 6; 8154 reached = 6;
7541 break; 8155 break;
7542 } 8156 }
7543 it_backup = *it; 8157 SAVE_IT (it_backup, *it, backup_data);
7544 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it))); 8158 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7545 skip2 = move_it_in_display_line_to (it, to_charpos, -1, 8159 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7546 op & MOVE_TO_POS); 8160 op & MOVE_TO_POS);
@@ -7554,7 +8168,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
7554 /* If TO_Y is in this line and TO_X was reached 8168 /* If TO_Y is in this line and TO_X was reached
7555 above, we scanned too far. We have to restore 8169 above, we scanned too far. We have to restore
7556 IT's settings to the ones before skipping. */ 8170 IT's settings to the ones before skipping. */
7557 *it = it_backup; 8171 RESTORE_IT (it, &it_backup, backup_data);
7558 reached = 6; 8172 reached = 6;
7559 } 8173 }
7560 else 8174 else
@@ -7581,7 +8195,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
7581 && it->line_wrap == WORD_WRAP) 8195 && it->line_wrap == WORD_WRAP)
7582 { 8196 {
7583 int prev_x = max (it->current_x - 1, 0); 8197 int prev_x = max (it->current_x - 1, 0);
7584 *it = it_backup; 8198 RESTORE_IT (it, &it_backup, backup_data);
7585 skip = move_it_in_display_line_to 8199 skip = move_it_in_display_line_to
7586 (it, -1, prev_x, MOVE_TO_X); 8200 (it, -1, prev_x, MOVE_TO_X);
7587 } 8201 }
@@ -7688,6 +8302,9 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
7688 last_max_ascent = it->max_ascent; 8302 last_max_ascent = it->max_ascent;
7689 } 8303 }
7690 8304
8305 if (backup_data)
8306 xfree (backup_data);
8307
7691 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); 8308 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7692} 8309}
7693 8310
@@ -7705,6 +8322,7 @@ move_it_vertically_backward (struct it *it, int dy)
7705{ 8322{
7706 int nlines, h; 8323 int nlines, h;
7707 struct it it2, it3; 8324 struct it it2, it3;
8325 void *it2data = NULL, *it3data = NULL;
7708 EMACS_INT start_pos; 8326 EMACS_INT start_pos;
7709 8327
7710 move_further_back: 8328 move_further_back:
@@ -7733,7 +8351,7 @@ move_it_vertically_backward (struct it *it, int dy)
7733 start of the next line so that we get its height. We need this 8351 start of the next line so that we get its height. We need this
7734 height to be able to tell whether we reached the specified 8352 height to be able to tell whether we reached the specified
7735 y-distance. */ 8353 y-distance. */
7736 it2 = *it; 8354 SAVE_IT (it2, *it, it2data);
7737 it2.max_ascent = it2.max_descent = 0; 8355 it2.max_ascent = it2.max_descent = 0;
7738 do 8356 do
7739 { 8357 {
@@ -7742,7 +8360,7 @@ move_it_vertically_backward (struct it *it, int dy)
7742 } 8360 }
7743 while (!IT_POS_VALID_AFTER_MOVE_P (&it2)); 8361 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7744 xassert (IT_CHARPOS (*it) >= BEGV); 8362 xassert (IT_CHARPOS (*it) >= BEGV);
7745 it3 = it2; 8363 SAVE_IT (it3, it2, it3data);
7746 8364
7747 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS); 8365 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7748 xassert (IT_CHARPOS (*it) >= BEGV); 8366 xassert (IT_CHARPOS (*it) >= BEGV);
@@ -7761,8 +8379,10 @@ move_it_vertically_backward (struct it *it, int dy)
7761 { 8379 {
7762 /* DY == 0 means move to the start of the screen line. The 8380 /* DY == 0 means move to the start of the screen line. The
7763 value of nlines is > 0 if continuation lines were involved. */ 8381 value of nlines is > 0 if continuation lines were involved. */
8382 RESTORE_IT (it, it, it2data);
7764 if (nlines > 0) 8383 if (nlines > 0)
7765 move_it_by_lines (it, nlines); 8384 move_it_by_lines (it, nlines);
8385 xfree (it3data);
7766 } 8386 }
7767 else 8387 else
7768 { 8388 {
@@ -7770,9 +8390,13 @@ move_it_vertically_backward (struct it *it, int dy)
7770 Note that H has been subtracted in front of the if-statement. */ 8390 Note that H has been subtracted in front of the if-statement. */
7771 int target_y = it->current_y + h - dy; 8391 int target_y = it->current_y + h - dy;
7772 int y0 = it3.current_y; 8392 int y0 = it3.current_y;
7773 int y1 = line_bottom_y (&it3); 8393 int y1;
7774 int line_height = y1 - y0; 8394 int line_height;
7775 8395
8396 RESTORE_IT (&it3, &it3, it3data);
8397 y1 = line_bottom_y (&it3);
8398 line_height = y1 - y0;
8399 RESTORE_IT (it, it, it2data);
7776 /* If we did not reach target_y, try to move further backward if 8400 /* If we did not reach target_y, try to move further backward if
7777 we can. If we moved too far backward, try to move forward. */ 8401 we can. If we moved too far backward, try to move forward. */
7778 if (target_y < it->current_y 8402 if (target_y < it->current_y
@@ -7899,6 +8523,7 @@ move_it_by_lines (struct it *it, int dvpos)
7899 else 8523 else
7900 { 8524 {
7901 struct it it2; 8525 struct it it2;
8526 void *it2data = NULL;
7902 EMACS_INT start_charpos, i; 8527 EMACS_INT start_charpos, i;
7903 8528
7904 /* Start at the beginning of the screen line containing IT's 8529 /* Start at the beginning of the screen line containing IT's
@@ -7934,7 +8559,7 @@ move_it_by_lines (struct it *it, int dvpos)
7934 8559
7935 /* Above call may have moved too far if continuation lines 8560 /* Above call may have moved too far if continuation lines
7936 are involved. Scan forward and see if it did. */ 8561 are involved. Scan forward and see if it did. */
7937 it2 = *it; 8562 SAVE_IT (it2, *it, it2data);
7938 it2.vpos = it2.current_y = 0; 8563 it2.vpos = it2.current_y = 0;
7939 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS); 8564 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7940 it->vpos -= it2.vpos; 8565 it->vpos -= it2.vpos;
@@ -7945,12 +8570,18 @@ move_it_by_lines (struct it *it, int dvpos)
7945 if (it2.vpos > -dvpos) 8570 if (it2.vpos > -dvpos)
7946 { 8571 {
7947 int delta = it2.vpos + dvpos; 8572 int delta = it2.vpos + dvpos;
7948 it2 = *it; 8573
8574 RESTORE_IT (&it2, &it2, it2data);
8575 SAVE_IT (it2, *it, it2data);
7949 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS); 8576 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7950 /* Move back again if we got too far ahead. */ 8577 /* Move back again if we got too far ahead. */
7951 if (IT_CHARPOS (*it) >= start_charpos) 8578 if (IT_CHARPOS (*it) >= start_charpos)
7952 *it = it2; 8579 RESTORE_IT (it, &it2, it2data);
8580 else
8581 xfree (it2data);
7953 } 8582 }
8583 else
8584 RESTORE_IT (it, it, it2data);
7954 } 8585 }
7955} 8586}
7956 8587
@@ -10437,7 +11068,7 @@ display_tool_bar_line (struct it *it, int height)
10437 ++i; 11068 ++i;
10438 } 11069 }
10439 11070
10440 /* Stop at line ends. */ 11071 /* Stop at line end. */
10441 if (ITERATOR_AT_END_OF_LINE_P (it)) 11072 if (ITERATOR_AT_END_OF_LINE_P (it))
10442 break; 11073 break;
10443 11074
@@ -10520,6 +11151,7 @@ tool_bar_lines_needed (struct frame *f, int *n_rows)
10520 it.first_visible_x = 0; 11151 it.first_visible_x = 0;
10521 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f); 11152 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10522 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); 11153 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11154 it.paragraph_embedding = L2R;
10523 11155
10524 while (!ITERATOR_AT_END_P (&it)) 11156 while (!ITERATOR_AT_END_P (&it))
10525 { 11157 {
@@ -10553,7 +11185,7 @@ DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10553 f = XFRAME (frame); 11185 f = XFRAME (frame);
10554 11186
10555 if (WINDOWP (f->tool_bar_window) 11187 if (WINDOWP (f->tool_bar_window)
10556 || (w = XWINDOW (f->tool_bar_window), 11188 && (w = XWINDOW (f->tool_bar_window),
10557 WINDOW_TOTAL_LINES (w) > 0)) 11189 WINDOW_TOTAL_LINES (w) > 0))
10558 { 11190 {
10559 update_tool_bar (f, 1); 11191 update_tool_bar (f, 1);
@@ -10602,6 +11234,14 @@ redisplay_tool_bar (struct frame *f)
10602 /* Build a string that represents the contents of the tool-bar. */ 11234 /* Build a string that represents the contents of the tool-bar. */
10603 build_desired_tool_bar_string (f); 11235 build_desired_tool_bar_string (f);
10604 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); 11236 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11237 /* FIXME: This should be controlled by a user option. But it
11238 doesn't make sense to have an R2L tool bar if the menu bar cannot
11239 be drawn also R2L, and making the menu bar R2L is tricky due
11240 toolkit-specific code that implements it. If an R2L tool bar is
11241 ever supported, display_tool_bar_line should also be augmented to
11242 call unproduce_glyphs like display_line and display_string
11243 do. */
11244 it.paragraph_embedding = L2R;
10605 11245
10606 if (f->n_tool_bar_rows == 0) 11246 if (f->n_tool_bar_rows == 0)
10607 { 11247 {
@@ -13296,14 +13936,18 @@ try_scrolling (Lisp_Object window, int just_this_one_p,
13296 which was computed as distance from window bottom to 13936 which was computed as distance from window bottom to
13297 point. This matters when lines at window top and lines 13937 point. This matters when lines at window top and lines
13298 below window bottom have different height. */ 13938 below window bottom have different height. */
13299 struct it it1 = it; 13939 struct it it1;
13940 void *it1data = NULL;
13300 /* We use a temporary it1 because line_bottom_y can modify 13941 /* We use a temporary it1 because line_bottom_y can modify
13301 its argument, if it moves one line down; see there. */ 13942 its argument, if it moves one line down; see there. */
13302 int start_y = line_bottom_y (&it1); 13943 int start_y;
13303 13944
13945 SAVE_IT (it1, it, it1data);
13946 start_y = line_bottom_y (&it1);
13304 do { 13947 do {
13948 RESTORE_IT (&it, &it, it1data);
13305 move_it_by_lines (&it, 1); 13949 move_it_by_lines (&it, 1);
13306 it1 = it; 13950 SAVE_IT (it1, it, it1data);
13307 } while (line_bottom_y (&it1) - start_y < amount_to_scroll); 13951 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13308 } 13952 }
13309 13953
@@ -14411,10 +15055,13 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
14411 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV) 15055 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
14412 { 15056 {
14413 struct it it1; 15057 struct it it1;
15058 void *it1data = NULL;
14414 15059
15060 SAVE_IT (it1, it, it1data);
14415 start_display (&it1, w, startp); 15061 start_display (&it1, w, startp);
14416 move_it_vertically (&it1, margin); 15062 move_it_vertically (&it1, margin);
14417 margin_pos = IT_CHARPOS (it1); 15063 margin_pos = IT_CHARPOS (it1);
15064 RESTORE_IT (&it, &it, it1data);
14418 } 15065 }
14419 scrolling_up = PT > margin_pos; 15066 scrolling_up = PT > margin_pos;
14420 aggressive = 15067 aggressive =
@@ -17306,6 +17953,8 @@ cursor_row_p (struct glyph_row *row)
17306static int 17953static int
17307push_display_prop (struct it *it, Lisp_Object prop) 17954push_display_prop (struct it *it, Lisp_Object prop)
17308{ 17955{
17956 xassert (it->method == GET_FROM_BUFFER);
17957
17309 push_it (it, NULL); 17958 push_it (it, NULL);
17310 17959
17311 if (STRINGP (prop)) 17960 if (STRINGP (prop))
@@ -17323,6 +17972,29 @@ push_display_prop (struct it *it, Lisp_Object prop)
17323 it->end_charpos = it->string_nchars = SCHARS (it->string); 17972 it->end_charpos = it->string_nchars = SCHARS (it->string);
17324 it->method = GET_FROM_STRING; 17973 it->method = GET_FROM_STRING;
17325 it->stop_charpos = 0; 17974 it->stop_charpos = 0;
17975 it->prev_stop = 0;
17976 it->base_level_stop = 0;
17977 it->string_from_display_prop_p = 1;
17978 it->from_disp_prop_p = 1;
17979
17980 /* Force paragraph direction to be that of the parent
17981 buffer. */
17982 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
17983 it->paragraph_embedding = it->bidi_it.paragraph_dir;
17984 else
17985 it->paragraph_embedding = L2R;
17986
17987 /* Set up the bidi iterator for this display string. */
17988 if (it->bidi_p)
17989 {
17990 it->bidi_it.string.lstring = it->string;
17991 it->bidi_it.string.s = NULL;
17992 it->bidi_it.string.schars = it->end_charpos;
17993 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
17994 it->bidi_it.string.from_disp_str = 1;
17995 it->bidi_it.string.unibyte = !it->multibyte_p;
17996 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
17997 }
17326 } 17998 }
17327 else if (CONSP (prop) && EQ (XCAR (prop), Qspace)) 17999 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17328 { 18000 {
@@ -17369,6 +18041,7 @@ static void
17369handle_line_prefix (struct it *it) 18041handle_line_prefix (struct it *it)
17370{ 18042{
17371 Lisp_Object prefix; 18043 Lisp_Object prefix;
18044
17372 if (it->continuation_lines_width > 0) 18045 if (it->continuation_lines_width > 0)
17373 { 18046 {
17374 prefix = get_it_property (it, Qwrap_prefix); 18047 prefix = get_it_property (it, Qwrap_prefix);
@@ -17394,9 +18067,9 @@ handle_line_prefix (struct it *it)
17394 18067
17395 18068
17396/* Remove N glyphs at the start of a reversed IT->glyph_row. Called 18069/* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17397 only for R2L lines from display_line, when it decides that too many 18070 only for R2L lines from display_line and display_string, when they
17398 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be 18071 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
17399 continued. */ 18072 the line/string needs to be continued on the next glyph row. */
17400static void 18073static void
17401unproduce_glyphs (struct it *it, int n) 18074unproduce_glyphs (struct it *it, int n)
17402{ 18075{
@@ -17426,12 +18099,13 @@ find_row_edges (struct it *it, struct glyph_row *row,
17426 lines' rows is implemented for bidi-reordered rows. */ 18099 lines' rows is implemented for bidi-reordered rows. */
17427 18100
17428 /* ROW->minpos is the value of min_pos, the minimal buffer position 18101 /* ROW->minpos is the value of min_pos, the minimal buffer position
17429 we have in ROW. */ 18102 we have in ROW, or ROW->start.pos if that is smaller. */
17430 if (min_pos <= ZV) 18103 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
17431 SET_TEXT_POS (row->minpos, min_pos, min_bpos); 18104 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17432 else 18105 else
17433 /* We didn't find _any_ valid buffer positions in any of the 18106 /* We didn't find buffer positions smaller than ROW->start, or
17434 glyphs, so we must trust the iterator's computed positions. */ 18107 didn't find _any_ valid buffer positions in any of the glyphs,
18108 so we must trust the iterator's computed positions. */
17435 row->minpos = row->start.pos; 18109 row->minpos = row->start.pos;
17436 if (max_pos <= 0) 18110 if (max_pos <= 0)
17437 { 18111 {
@@ -17506,6 +18180,7 @@ display_line (struct it *it)
17506 struct glyph_row *row = it->glyph_row; 18180 struct glyph_row *row = it->glyph_row;
17507 Lisp_Object overlay_arrow_string; 18181 Lisp_Object overlay_arrow_string;
17508 struct it wrap_it; 18182 struct it wrap_it;
18183 void *wrap_data = NULL;
17509 int may_wrap = 0, wrap_x IF_LINT (= 0); 18184 int may_wrap = 0, wrap_x IF_LINT (= 0);
17510 int wrap_row_used = -1; 18185 int wrap_row_used = -1;
17511 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0); 18186 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
@@ -17660,7 +18335,7 @@ display_line (struct it *it)
17660 may_wrap = 1; 18335 may_wrap = 1;
17661 else if (may_wrap) 18336 else if (may_wrap)
17662 { 18337 {
17663 wrap_it = *it; 18338 SAVE_IT (wrap_it, *it, wrap_data);
17664 wrap_x = x; 18339 wrap_x = x;
17665 wrap_row_used = row->used[TEXT_AREA]; 18340 wrap_row_used = row->used[TEXT_AREA];
17666 wrap_row_ascent = row->ascent; 18341 wrap_row_ascent = row->ascent;
@@ -17830,7 +18505,7 @@ display_line (struct it *it)
17830 if (row->reversed_p) 18505 if (row->reversed_p)
17831 unproduce_glyphs (it, 18506 unproduce_glyphs (it,
17832 row->used[TEXT_AREA] - wrap_row_used); 18507 row->used[TEXT_AREA] - wrap_row_used);
17833 *it = wrap_it; 18508 RESTORE_IT (it, &wrap_it, wrap_data);
17834 it->continuation_lines_width += wrap_x; 18509 it->continuation_lines_width += wrap_x;
17835 row->used[TEXT_AREA] = wrap_row_used; 18510 row->used[TEXT_AREA] = wrap_row_used;
17836 row->ascent = wrap_row_ascent; 18511 row->ascent = wrap_row_ascent;
@@ -18236,6 +18911,8 @@ See also `bidi-paragraph-direction'. */)
18236 itb.charpos = pos; 18911 itb.charpos = pos;
18237 itb.bytepos = bytepos; 18912 itb.bytepos = bytepos;
18238 itb.nchars = -1; 18913 itb.nchars = -1;
18914 itb.string.s = NULL;
18915 itb.string.lstring = Qnil;
18239 itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */ 18916 itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
18240 itb.first_elt = 1; 18917 itb.first_elt = 1;
18241 itb.separator_limit = -1; 18918 itb.separator_limit = -1;
@@ -18325,6 +19002,11 @@ display_menu_bar (struct window *w)
18325 } 19002 }
18326#endif /* not USE_X_TOOLKIT */ 19003#endif /* not USE_X_TOOLKIT */
18327 19004
19005 /* FIXME: This should be controlled by a user option. See the
19006 comments in redisplay_tool_bar and display_mode_line about
19007 this. */
19008 it.paragraph_embedding = L2R;
19009
18328 if (! mode_line_inverse_video) 19010 if (! mode_line_inverse_video)
18329 /* Force the menu-bar to be displayed in the default face. */ 19011 /* Force the menu-bar to be displayed in the default face. */
18330 it.base_face_id = it.face_id = DEFAULT_FACE_ID; 19012 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
@@ -18502,6 +19184,11 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18502 /* Force the mode-line to be displayed in the default face. */ 19184 /* Force the mode-line to be displayed in the default face. */
18503 it.base_face_id = it.face_id = DEFAULT_FACE_ID; 19185 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18504 19186
19187 /* FIXME: This should be controlled by a user option. But
19188 supporting such an option is not trivial, since the mode line is
19189 made up of many separate strings. */
19190 it.paragraph_embedding = L2R;
19191
18505 record_unwind_protect (unwind_format_mode_line, 19192 record_unwind_protect (unwind_format_mode_line,
18506 format_mode_line_unwind_data (NULL, Qnil, 0)); 19193 format_mode_line_unwind_data (NULL, Qnil, 0));
18507 19194
@@ -20047,6 +20734,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20047 int hpos_at_start = it->hpos; 20734 int hpos_at_start = it->hpos;
20048 int saved_face_id = it->face_id; 20735 int saved_face_id = it->face_id;
20049 struct glyph_row *row = it->glyph_row; 20736 struct glyph_row *row = it->glyph_row;
20737 EMACS_INT it_charpos;
20050 20738
20051 /* Initialize the iterator IT for iteration over STRING beginning 20739 /* Initialize the iterator IT for iteration over STRING beginning
20052 with index START. */ 20740 with index START. */
@@ -20055,10 +20743,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20055 if (string && STRINGP (lisp_string)) 20743 if (string && STRINGP (lisp_string))
20056 /* LISP_STRING is the one returned by decode_mode_spec. We should 20744 /* LISP_STRING is the one returned by decode_mode_spec. We should
20057 ignore its text properties. */ 20745 ignore its text properties. */
20058 it->stop_charpos = -1; 20746 it->stop_charpos = it->end_charpos;
20059 20747
20060 /* If displaying STRING, set up the face of the iterator 20748 /* If displaying STRING, set up the face of the iterator from
20061 from LISP_STRING, if that's given. */ 20749 FACE_STRING, if that's given. */
20062 if (STRINGP (face_string)) 20750 if (STRINGP (face_string))
20063 { 20751 {
20064 EMACS_INT endptr; 20752 EMACS_INT endptr;
@@ -20092,6 +20780,11 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20092 row->phys_height = it->max_phys_ascent + it->max_phys_descent; 20780 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20093 row->extra_line_spacing = it->max_extra_line_spacing; 20781 row->extra_line_spacing = it->max_extra_line_spacing;
20094 20782
20783 if (STRINGP (it->string))
20784 it_charpos = IT_STRING_CHARPOS (*it);
20785 else
20786 it_charpos = IT_CHARPOS (*it);
20787
20095 /* This condition is for the case that we are called with current_x 20788 /* This condition is for the case that we are called with current_x
20096 past last_visible_x. */ 20789 past last_visible_x. */
20097 while (it->current_x < max_x) 20790 while (it->current_x < max_x)
@@ -20104,10 +20797,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20104 20797
20105 /* Produce glyphs. */ 20798 /* Produce glyphs. */
20106 x_before = it->current_x; 20799 x_before = it->current_x;
20107 n_glyphs_before = it->glyph_row->used[TEXT_AREA]; 20800 n_glyphs_before = row->used[TEXT_AREA];
20108 PRODUCE_GLYPHS (it); 20801 PRODUCE_GLYPHS (it);
20109 20802
20110 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before; 20803 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
20111 i = 0; 20804 i = 0;
20112 x = x_before; 20805 x = x_before;
20113 while (i < nglyphs) 20806 while (i < nglyphs)
@@ -20121,12 +20814,18 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20121 if (CHAR_GLYPH_PADDING_P (*glyph)) 20814 if (CHAR_GLYPH_PADDING_P (*glyph))
20122 { 20815 {
20123 /* A wide character is unbreakable. */ 20816 /* A wide character is unbreakable. */
20124 it->glyph_row->used[TEXT_AREA] = n_glyphs_before; 20817 if (row->reversed_p)
20818 unproduce_glyphs (it, row->used[TEXT_AREA]
20819 - n_glyphs_before);
20820 row->used[TEXT_AREA] = n_glyphs_before;
20125 it->current_x = x_before; 20821 it->current_x = x_before;
20126 } 20822 }
20127 else 20823 else
20128 { 20824 {
20129 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i; 20825 if (row->reversed_p)
20826 unproduce_glyphs (it, row->used[TEXT_AREA]
20827 - (n_glyphs_before + i));
20828 row->used[TEXT_AREA] = n_glyphs_before + i;
20130 it->current_x = x; 20829 it->current_x = x;
20131 } 20830 }
20132 break; 20831 break;
@@ -20136,7 +20835,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20136 /* Glyph is at least partially visible. */ 20835 /* Glyph is at least partially visible. */
20137 ++it->hpos; 20836 ++it->hpos;
20138 if (x < it->first_visible_x) 20837 if (x < it->first_visible_x)
20139 it->glyph_row->x = x - it->first_visible_x; 20838 row->x = x - it->first_visible_x;
20140 } 20839 }
20141 else 20840 else
20142 { 20841 {
@@ -20168,6 +20867,10 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20168 } 20867 }
20169 20868
20170 set_iterator_to_next (it, 1); 20869 set_iterator_to_next (it, 1);
20870 if (STRINGP (it->string))
20871 it_charpos = IT_STRING_CHARPOS (*it);
20872 else
20873 it_charpos = IT_CHARPOS (*it);
20171 20874
20172 /* Stop if truncating at the right edge. */ 20875 /* Stop if truncating at the right edge. */
20173 if (it->line_wrap == TRUNCATE 20876 if (it->line_wrap == TRUNCATE
@@ -20175,7 +20878,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20175 { 20878 {
20176 /* Add truncation mark, but don't do it if the line is 20879 /* Add truncation mark, but don't do it if the line is
20177 truncated at a padding space. */ 20880 truncated at a padding space. */
20178 if (IT_CHARPOS (*it) < it->string_nchars) 20881 if (it_charpos < it->string_nchars)
20179 { 20882 {
20180 if (!FRAME_WINDOW_P (it->f)) 20883 if (!FRAME_WINDOW_P (it->f))
20181 { 20884 {
@@ -20183,9 +20886,20 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20183 20886
20184 if (it->current_x > it->last_visible_x) 20887 if (it->current_x > it->last_visible_x)
20185 { 20888 {
20186 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii) 20889 if (!row->reversed_p)
20187 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii])) 20890 {
20188 break; 20891 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
20892 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
20893 break;
20894 }
20895 else
20896 {
20897 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
20898 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
20899 break;
20900 unproduce_glyphs (it, ii + 1);
20901 ii = row->used[TEXT_AREA] - (ii + 1);
20902 }
20189 for (n = row->used[TEXT_AREA]; ii < n; ++ii) 20903 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
20190 { 20904 {
20191 row->used[TEXT_AREA] = ii; 20905 row->used[TEXT_AREA] = ii;
@@ -20194,7 +20908,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20194 } 20908 }
20195 produce_special_glyphs (it, IT_TRUNCATION); 20909 produce_special_glyphs (it, IT_TRUNCATION);
20196 } 20910 }
20197 it->glyph_row->truncated_on_right_p = 1; 20911 row->truncated_on_right_p = 1;
20198 } 20912 }
20199 break; 20913 break;
20200 } 20914 }
@@ -20202,11 +20916,11 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st
20202 20916
20203 /* Maybe insert a truncation at the left. */ 20917 /* Maybe insert a truncation at the left. */
20204 if (it->first_visible_x 20918 if (it->first_visible_x
20205 && IT_CHARPOS (*it) > 0) 20919 && it_charpos > 0)
20206 { 20920 {
20207 if (!FRAME_WINDOW_P (it->f)) 20921 if (!FRAME_WINDOW_P (it->f))
20208 insert_left_trunc_glyphs (it); 20922 insert_left_trunc_glyphs (it);
20209 it->glyph_row->truncated_on_left_p = 1; 20923 row->truncated_on_left_p = 1;
20210 } 20924 }
20211 20925
20212 it->face_id = saved_face_id; 20926 it->face_id = saved_face_id;
@@ -27051,18 +27765,18 @@ but does not change the fact they are interpreted as raw bytes. */);
27051 unibyte_display_via_language_environment = 0; 27765 unibyte_display_via_language_environment = 0;
27052 27766
27053 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height, 27767 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
27054 doc: /* *Maximum height for resizing mini-windows. 27768 doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
27055If a float, it specifies a fraction of the mini-window frame's height. 27769If a float, it specifies a fraction of the mini-window frame's height.
27056If an integer, it specifies a number of lines. */); 27770If an integer, it specifies a number of lines. */);
27057 Vmax_mini_window_height = make_float (0.25); 27771 Vmax_mini_window_height = make_float (0.25);
27058 27772
27059 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows, 27773 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
27060 doc: /* *How to resize mini-windows. 27774 doc: /* How to resize mini-windows (the minibuffer and the echo area).
27061A value of nil means don't automatically resize mini-windows. 27775A value of nil means don't automatically resize mini-windows.
27062A value of t means resize them to fit the text displayed in them. 27776A value of t means resize them to fit the text displayed in them.
27063A value of `grow-only', the default, means let mini-windows grow 27777A value of `grow-only', the default, means let mini-windows grow only;
27064only, until their display becomes empty, at which point the windows 27778they return to their normal size when the minibuffer is closed, or the
27065go back to their normal size. */); 27779echo area becomes empty. */);
27066 Vresize_mini_windows = Qgrow_only; 27780 Vresize_mini_windows = Qgrow_only;
27067 27781
27068 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist, 27782 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
diff --git a/src/xfaces.c b/src/xfaces.c
index 4f06bd3ba55..c1e75ab3e59 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -536,8 +536,7 @@ int color_count[256];
536/* Register color PIXEL as allocated. */ 536/* Register color PIXEL as allocated. */
537 537
538void 538void
539register_color (pixel) 539register_color (unsigned long pixel)
540 unsigned long pixel;
541{ 540{
542 xassert (pixel < 256); 541 xassert (pixel < 256);
543 ++color_count[pixel]; 542 ++color_count[pixel];
@@ -547,8 +546,7 @@ register_color (pixel)
547/* Register color PIXEL as deallocated. */ 546/* Register color PIXEL as deallocated. */
548 547
549void 548void
550unregister_color (pixel) 549unregister_color (unsigned long pixel)
551 unsigned long pixel;
552{ 550{
553 xassert (pixel < 256); 551 xassert (pixel < 256);
554 if (color_count[pixel] > 0) 552 if (color_count[pixel] > 0)
@@ -561,9 +559,7 @@ unregister_color (pixel)
561/* Register N colors from PIXELS as deallocated. */ 559/* Register N colors from PIXELS as deallocated. */
562 560
563void 561void
564unregister_colors (pixels, n) 562unregister_colors (unsigned long *pixels, int n)
565 unsigned long *pixels;
566 int n;
567{ 563{
568 int i; 564 int i;
569 for (i = 0; i < n; ++i) 565 for (i = 0; i < n; ++i)
@@ -3813,6 +3809,18 @@ Default face attributes override any local face attributes. */)
3813 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name), 3809 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, name),
3814 Qnil)); 3810 Qnil));
3815 } 3811 }
3812
3813 if (STRINGP (gvec[LFACE_FOREGROUND_INDEX]))
3814 Fmodify_frame_parameters (frame,
3815 Fcons (Fcons (Qforeground_color,
3816 gvec[LFACE_FOREGROUND_INDEX]),
3817 Qnil));
3818
3819 if (STRINGP (gvec[LFACE_BACKGROUND_INDEX]))
3820 Fmodify_frame_parameters (frame,
3821 Fcons (Fcons (Qbackground_color,
3822 gvec[LFACE_BACKGROUND_INDEX]),
3823 Qnil));
3816 } 3824 }
3817 } 3825 }
3818 3826
diff --git a/src/xfns.c b/src/xfns.c
index b4153973e0d..11bf9ab57e1 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2001,11 +2001,8 @@ xic_create_fontsetname (const char *base_fontname, int motif)
2001 2001
2002#ifdef DEBUG_XIC_FONTSET 2002#ifdef DEBUG_XIC_FONTSET
2003static void 2003static void
2004print_fontset_result (xfs, name, missing_list, missing_count) 2004print_fontset_result (XFontSet xfs, char *name, char **missing_list,
2005 XFontSet xfs; 2005 int missing_count)
2006 char *name;
2007 char **missing_list;
2008 int missing_count;
2009{ 2006{
2010 if (xfs) 2007 if (xfs)
2011 fprintf (stderr, "XIC Fontset created: %s\n", name); 2008 fprintf (stderr, "XIC Fontset created: %s\n", name);
@@ -5805,10 +5802,6 @@ syms_of_xfns (void)
5805 DEFSYM (Qfont_param, "font-parameter"); 5802 DEFSYM (Qfont_param, "font-parameter");
5806 /* This is the end of symbol initialization. */ 5803 /* This is the end of symbol initialization. */
5807 5804
5808 /* Text property `display' should be nonsticky by default. */
5809 Vtext_property_default_nonsticky
5810 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
5811
5812 Fput (Qundefined_color, Qerror_conditions, 5805 Fput (Qundefined_color, Qerror_conditions,
5813 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil))); 5806 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
5814 Fput (Qundefined_color, Qerror_message, 5807 Fput (Qundefined_color, Qerror_message,
diff --git a/src/xgselect.c b/src/xgselect.c
index 0d154f6496a..9ccdd37489f 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -15,14 +15,14 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details. 15GNU General Public License for more details.
16 16
17You should have received a copy of the GNU General Public License 17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 18along with GNU Emacs. If not, see <http§://www.gnu.org/licenses/>. */
19 19
20#include <config.h> 20#include <config.h>
21 21
22#include <setjmp.h> 22#include <setjmp.h>
23#include "xgselect.h" 23#include "xgselect.h"
24 24
25#if defined (USE_GTK) || defined (HAVE_GCONF) 25#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
26 26
27#include <glib.h> 27#include <glib.h>
28#include <errno.h> 28#include <errno.h>
@@ -149,13 +149,13 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
149 149
150 return retval; 150 return retval;
151} 151}
152#endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ 152#endif /* USE_GTK || HAVE_GCONF || HAVE_GSETTINGS */
153 153
154void 154void
155xgselect_initialize (void) 155xgselect_initialize (void)
156{ 156{
157#if defined (USE_GTK) || defined (HAVE_GCONF) 157#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
158 gfds_size = 128; 158 gfds_size = 128;
159 gfds = xmalloc (sizeof (*gfds)*gfds_size); 159 gfds = xmalloc (sizeof (*gfds)*gfds_size);
160#endif /* defined (USE_GTK) || defined (HAVE_GCONF) */ 160#endif
161} 161}
diff --git a/src/xmenu.c b/src/xmenu.c
index fc629b35104..b4338c1d653 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -740,10 +740,13 @@ menu_highlight_callback (GtkWidget *widget, gpointer call_data)
740 help = call_data ? cb_data->help : Qnil; 740 help = call_data ? cb_data->help : Qnil;
741 741
742 /* If popup_activated_flag is greater than 1 we are in a popup menu. 742 /* If popup_activated_flag is greater than 1 we are in a popup menu.
743 Don't show help for them, they won't appear before the 743 Don't pass the frame to show_help_event for those.
744 popup is popped down. */ 744 Passing frame creates an Emacs event. As we are looping in
745 if (popup_activated_flag <= 1) 745 popup_widget_loop, it won't be handeled. Passing NULL shows the tip
746 show_help_event (cb_data->cl_data->f, widget, help); 746 directly without using an Emacs event. This is what the Lucid code
747 does below. */
748 show_help_event (popup_activated_flag <= 1 ? cb_data->cl_data->f : NULL,
749 widget, help);
747} 750}
748#else 751#else
749static void 752static void
diff --git a/src/xrdb.c b/src/xrdb.c
index e18ff65f799..6a16e3260bd 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -651,9 +651,7 @@ typedef char **List;
651#define free_arglist(list) 651#define free_arglist(list)
652 652
653static List 653static List
654member (elt, list) 654member (char *elt, List list)
655 char *elt;
656 List list;
657{ 655{
658 List p; 656 List p;
659 657
@@ -665,20 +663,17 @@ member (elt, list)
665} 663}
666 664
667static void 665static void
668fatal (msg, prog, x1, x2, x3, x4, x5) 666fatal (char *msg, char *prog)
669 char *msg, *prog;
670 int x1, x2, x3, x4, x5;
671{ 667{
672 if (errno) 668 if (errno)
673 perror (prog); 669 perror (prog);
674 670
675 (void) fprintf (stderr, msg, prog, x1, x2, x3, x4, x5); 671 (void) fprintf (stderr, msg, prog);
676 exit (1); 672 exit (1);
677} 673}
678 674
679main (argc, argv) 675int
680 int argc; 676main (int argc, char **argv)
681 char **argv;
682{ 677{
683 Display *display; 678 Display *display;
684 char *displayname, *resource_string, *class, *name; 679 char *displayname, *resource_string, *class, *name;
@@ -749,5 +744,7 @@ main (argc, argv)
749 printf ("\tExit.\n\n"); 744 printf ("\tExit.\n\n");
750 745
751 XCloseDisplay (display); 746 XCloseDisplay (display);
747
748 return 0;
752} 749}
753#endif /* TESTRM */ 750#endif /* TESTRM */
diff --git a/src/xselect.c b/src/xselect.c
index 7f4e0b40f62..5e5bdb55eca 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -112,6 +112,7 @@ static Lisp_Object QUTF8_STRING; /* This is a type of selection. */
112static Lisp_Object Qcompound_text_with_extensions; 112static Lisp_Object Qcompound_text_with_extensions;
113 113
114static Lisp_Object Qforeign_selection; 114static Lisp_Object Qforeign_selection;
115static Lisp_Object Qx_lost_selection_functions, Qx_sent_selection_functions;
115 116
116/* If this is a smaller number than the max-request-size of the display, 117/* If this is a smaller number than the max-request-size of the display,
117 emacs will use INCR selection transfer when the selection is larger 118 emacs will use INCR selection transfer when the selection is larger
@@ -855,7 +856,7 @@ x_handle_selection_request (struct input_event *event)
855 && !EQ (Vx_sent_selection_functions, Qunbound)) 856 && !EQ (Vx_sent_selection_functions, Qunbound))
856 { 857 {
857 Lisp_Object args[4]; 858 Lisp_Object args[4];
858 args[0] = Vx_sent_selection_functions; 859 args[0] = Qx_sent_selection_functions;
859 args[1] = selection_symbol; 860 args[1] = selection_symbol;
860 args[2] = target_symbol; 861 args[2] = target_symbol;
861 args[3] = success ? Qt : Qnil; 862 args[3] = success ? Qt : Qnil;
@@ -979,7 +980,7 @@ x_handle_selection_clear (struct input_event *event)
979 /* Run the `x-lost-selection-functions' abnormal hook. */ 980 /* Run the `x-lost-selection-functions' abnormal hook. */
980 { 981 {
981 Lisp_Object args[2]; 982 Lisp_Object args[2];
982 args[0] = Vx_lost_selection_functions; 983 args[0] = Qx_lost_selection_functions;
983 args[1] = selection_symbol; 984 args[1] = selection_symbol;
984 Frun_hook_with_args (2, args); 985 Frun_hook_with_args (2, args);
985 } 986 }
@@ -1020,7 +1021,7 @@ x_clear_frame_selections (FRAME_PTR f)
1020 { 1021 {
1021 /* Run the `x-lost-selection-functions' abnormal hook. */ 1022 /* Run the `x-lost-selection-functions' abnormal hook. */
1022 Lisp_Object args[2]; 1023 Lisp_Object args[2];
1023 args[0] = Vx_lost_selection_functions; 1024 args[0] = Qx_lost_selection_functions;
1024 args[1] = Fcar (Fcar (t->Vselection_alist)); 1025 args[1] = Fcar (Fcar (t->Vselection_alist));
1025 Frun_hook_with_args (2, args); 1026 Frun_hook_with_args (2, args);
1026 1027
@@ -1033,7 +1034,7 @@ x_clear_frame_selections (FRAME_PTR f)
1033 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest)))))))) 1034 && EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
1034 { 1035 {
1035 Lisp_Object args[2]; 1036 Lisp_Object args[2];
1036 args[0] = Vx_lost_selection_functions; 1037 args[0] = Qx_lost_selection_functions;
1037 args[1] = XCAR (XCAR (XCDR (rest))); 1038 args[1] = XCAR (XCAR (XCDR (rest)));
1038 Frun_hook_with_args (2, args); 1039 Frun_hook_with_args (2, args);
1039 XSETCDR (rest, XCDR (XCDR (rest))); 1040 XSETCDR (rest, XCDR (XCDR (rest)));
@@ -2679,4 +2680,6 @@ A value of 0 means wait as long as necessary. This is initialized from the
2679 DEFSYM (QNULL, "NULL"); 2680 DEFSYM (QNULL, "NULL");
2680 DEFSYM (Qcompound_text_with_extensions, "compound-text-with-extensions"); 2681 DEFSYM (Qcompound_text_with_extensions, "compound-text-with-extensions");
2681 DEFSYM (Qforeign_selection, "foreign-selection"); 2682 DEFSYM (Qforeign_selection, "foreign-selection");
2683 DEFSYM (Qx_lost_selection_functions, "x-lost-selection-functions");
2684 DEFSYM (Qx_sent_selection_functions, "x-sent-selection-functions");
2682} 2685}
diff --git a/src/xsettings.c b/src/xsettings.c
index 5412cf426f8..dadbe68b4cb 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -34,9 +34,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
34 34
35#include <X11/Xproto.h> 35#include <X11/Xproto.h>
36 36
37#ifdef HAVE_GSETTINGS
38#include <glib-object.h>
39#include <gio/gio.h>
40#endif
41
37#ifdef HAVE_GCONF 42#ifdef HAVE_GCONF
38#include <gconf/gconf-client.h> 43#include <gconf/gconf-client.h>
39#endif 44#endif
45
40#ifdef HAVE_XFT 46#ifdef HAVE_XFT
41#include <X11/Xft/Xft.h> 47#include <X11/Xft/Xft.h>
42#endif 48#endif
@@ -48,10 +54,7 @@ static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render,
48 Qtool_bar_style; 54 Qtool_bar_style;
49static Lisp_Object current_tool_bar_style; 55static Lisp_Object current_tool_bar_style;
50 56
51#ifdef HAVE_GCONF 57/* Store an config changed event in to the event queue. */
52static GConfClient *gconf_client;
53#endif
54
55 58
56static void 59static void
57store_config_changed_event (Lisp_Object arg, Lisp_Object display_name) 60store_config_changed_event (Lisp_Object arg, Lisp_Object display_name)
@@ -64,6 +67,99 @@ store_config_changed_event (Lisp_Object arg, Lisp_Object display_name)
64 kbd_buffer_store_event (&event); 67 kbd_buffer_store_event (&event);
65} 68}
66 69
70/* Return non-zero if DPYINFO is still valid. */
71static int
72dpyinfo_valid (struct x_display_info *dpyinfo)
73{
74 int found = 0;
75 if (dpyinfo != NULL)
76 {
77 struct x_display_info *d;
78 for (d = x_display_list; !found && d; d = d->next)
79 found = d == dpyinfo && d->display == dpyinfo->display;
80 }
81 return found;
82}
83
84/* Store a monospace font change event if the monospaced font changed. */
85
86#if defined HAVE_XFT && (defined HAVE_GSETTINGS || defined HAVE_GCONF)
87static void
88store_monospaced_changed (const char *newfont)
89{
90 if (current_mono_font != NULL && strcmp (newfont, current_mono_font) == 0)
91 return; /* No change. */
92
93 xfree (current_mono_font);
94 current_mono_font = xstrdup (newfont);
95
96 if (dpyinfo_valid (first_dpyinfo) && use_system_font)
97 {
98 store_config_changed_event (Qmonospace_font_name,
99 XCAR (first_dpyinfo->name_list_element));
100 }
101}
102#endif
103
104/* Store a font name change event if the font name changed. */
105
106#ifdef HAVE_XFT
107static void
108store_font_name_changed (const char *newfont)
109{
110 if (current_font != NULL && strcmp (newfont, current_font) == 0)
111 return; /* No change. */
112
113 xfree (current_font);
114 current_font = xstrdup (newfont);
115
116 if (dpyinfo_valid (first_dpyinfo))
117 {
118 store_config_changed_event (Qfont_name,
119 XCAR (first_dpyinfo->name_list_element));
120 }
121}
122#endif /* HAVE_XFT */
123
124/* Map TOOL_BAR_STYLE from a string to its correspinding Lisp value.
125 Return Qnil if TOOL_BAR_STYLE is not known. */
126
127static Lisp_Object
128map_tool_bar_style (const char *tool_bar_style)
129{
130 Lisp_Object style = Qnil;
131 if (tool_bar_style)
132 {
133 if (strcmp (tool_bar_style, "both") == 0)
134 style = Qboth;
135 else if (strcmp (tool_bar_style, "both-horiz") == 0)
136 style = Qboth_horiz;
137 else if (strcmp (tool_bar_style, "icons") == 0)
138 style = Qimage;
139 else if (strcmp (tool_bar_style, "text") == 0)
140 style = Qtext;
141 }
142
143 return style;
144}
145
146/* Store a tool bar style change event if the tool bar style changed. */
147
148static void
149store_tool_bar_style_changed (const char *newstyle,
150 struct x_display_info *dpyinfo)
151{
152 Lisp_Object style = map_tool_bar_style (newstyle);
153 if (EQ (current_tool_bar_style, style))
154 return; /* No change. */
155
156 current_tool_bar_style = style;
157 if (dpyinfo_valid (dpyinfo))
158 store_config_changed_event (Qtool_bar_style,
159 XCAR (dpyinfo->name_list_element));
160}
161
162
67#define XSETTINGS_FONT_NAME "Gtk/FontName" 163#define XSETTINGS_FONT_NAME "Gtk/FontName"
68#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle" 164#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle"
69 165
@@ -83,55 +179,128 @@ struct xsettings
83 FcBool aa, hinting; 179 FcBool aa, hinting;
84 int rgba, lcdfilter, hintstyle; 180 int rgba, lcdfilter, hintstyle;
85 double dpi; 181 double dpi;
86#endif
87 182
88 char *font; 183 char *font;
184#endif
185
89 char *tb_style; 186 char *tb_style;
90 187
91 unsigned seen; 188 unsigned seen;
92}; 189};
93 190
191#ifdef HAVE_GSETTINGS
192#define GSETTINGS_SCHEMA "org.gnome.desktop.interface"
193#define GSETTINGS_TOOL_BAR_STYLE "toolbar-style"
194
195#ifdef HAVE_XFT
196#define GSETTINGS_MONO_FONT "monospace-font-name"
197#define GSETTINGS_FONT_NAME "font-name"
198#endif
199
200
201/* The single GSettings instance, or NULL if not connected to GSettings. */
202
203static GSettings *gsettings_client;
204
205/* Callback called when something changed in GSettings. */
206
207static void
208something_changed_gsettingsCB (GSettings *settings,
209 gchar *key,
210 gpointer user_data)
211{
212 GVariant *val;
213
214 if (strcmp (key, GSETTINGS_TOOL_BAR_STYLE) == 0)
215 {
216 val = g_settings_get_value (settings, GSETTINGS_TOOL_BAR_STYLE);
217 if (val)
218 {
219 g_variant_ref_sink (val);
220 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
221 {
222 const gchar *newstyle = g_variant_get_string (val, NULL);
223 store_tool_bar_style_changed (newstyle, first_dpyinfo);
224 }
225 g_variant_unref (val);
226 }
227 }
228#ifdef HAVE_XFT
229 else if (strcmp (key, GSETTINGS_MONO_FONT) == 0)
230 {
231 val = g_settings_get_value (settings, GSETTINGS_MONO_FONT);
232 if (val)
233 {
234 g_variant_ref_sink (val);
235 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
236 {
237 const gchar *newfont = g_variant_get_string (val, NULL);
238 store_monospaced_changed (newfont);
239 }
240 g_variant_unref (val);
241 }
242 }
243 else if (strcmp (key, GSETTINGS_FONT_NAME) == 0)
244 {
245 val = g_settings_get_value (settings, GSETTINGS_FONT_NAME);
246 if (val)
247 {
248 g_variant_ref_sink (val);
249 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
250 {
251 const gchar *newfont = g_variant_get_string (val, NULL);
252 store_font_name_changed (newfont);
253 }
254 g_variant_unref (val);
255 }
256 }
257#endif /* HAVE_XFT */
258}
259
260#endif /* HAVE_GSETTINGS */
261
94#ifdef HAVE_GCONF 262#ifdef HAVE_GCONF
263#define GCONF_TOOL_BAR_STYLE "/desktop/gnome/interface/toolbar_style"
264#ifdef HAVE_XFT
265#define GCONF_MONO_FONT "/desktop/gnome/interface/monospace_font_name"
266#define GCONF_FONT_NAME "/desktop/gnome/interface/font_name"
267#endif
95 268
96#define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name" 269/* The single GConf instance, or NULL if not connected to GConf. */
97#define SYSTEM_FONT "/desktop/gnome/interface/font_name" 270
271static GConfClient *gconf_client;
98 272
99/* Callback called when something changed in GConf that we care about, 273/* Callback called when something changed in GConf that we care about. */
100 that is SYSTEM_MONO_FONT. */
101 274
102static void 275static void
103something_changedCB (GConfClient *client, 276something_changed_gconfCB (GConfClient *client,
104 guint cnxn_id, 277 guint cnxn_id,
105 GConfEntry *entry, 278 GConfEntry *entry,
106 gpointer user_data) 279 gpointer user_data)
107{ 280{
108 GConfValue *v = gconf_entry_get_value (entry); 281 GConfValue *v = gconf_entry_get_value (entry);
282 const char *key = gconf_entry_get_key (entry);
109 283
110 if (!v) return; 284 if (!v || v->type != GCONF_VALUE_STRING || ! key) return;
111 if (v->type == GCONF_VALUE_STRING) 285 if (strcmp (key, GCONF_TOOL_BAR_STYLE) == 0)
112 { 286 {
113 const char *value = gconf_value_get_string (v); 287 const char *value = gconf_value_get_string (v);
114 if (current_mono_font != NULL && strcmp (value, current_mono_font) == 0) 288 store_tool_bar_style_changed (value, first_dpyinfo);
115 return; /* No change. */
116
117 xfree (current_mono_font);
118 current_mono_font = xstrdup (value);
119 } 289 }
120 290#ifdef HAVE_XFT
121 291 else if (strcmp (key, GCONF_MONO_FONT) == 0)
122 if (first_dpyinfo != NULL) 292 {
293 const char *value = gconf_value_get_string (v);
294 store_monospaced_changed (value);
295 }
296 else if (strcmp (key, GCONF_FONT_NAME) == 0)
123 { 297 {
124 /* Check if display still open */ 298 const char *value = gconf_value_get_string (v);
125 struct x_display_info *dpyinfo; 299 store_font_name_changed (value);
126 int found = 0;
127 for (dpyinfo = x_display_list; !found && dpyinfo; dpyinfo = dpyinfo->next)
128 found = dpyinfo == first_dpyinfo;
129
130 if (found && use_system_font)
131 store_config_changed_event (Qmonospace_font_name,
132 XCAR (first_dpyinfo->name_list_element));
133 } 300 }
301#endif /* HAVE_XFT */
134} 302}
303
135#endif /* HAVE_GCONF */ 304#endif /* HAVE_GCONF */
136 305
137#ifdef HAVE_XFT 306#ifdef HAVE_XFT
@@ -277,10 +446,10 @@ parse_settings (unsigned char *prop,
277 want_this = 446 want_this =
278#ifdef HAVE_XFT 447#ifdef HAVE_XFT
279 (nlen > 6 && strncmp (name, "Xft/", 4) == 0) 448 (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
449 || strcmp (XSETTINGS_FONT_NAME, name) == 0
280 || 450 ||
281#endif 451#endif
282 (strcmp (XSETTINGS_FONT_NAME, name) == 0) 452 strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0;
283 || (strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0);
284 453
285 switch (type) 454 switch (type)
286 { 455 {
@@ -322,17 +491,17 @@ parse_settings (unsigned char *prop,
322 if (want_this) 491 if (want_this)
323 { 492 {
324 ++settings_seen; 493 ++settings_seen;
325 if (strcmp (name, XSETTINGS_FONT_NAME) == 0) 494 if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
326 {
327 settings->font = xstrdup (sval);
328 settings->seen |= SEEN_FONT;
329 }
330 else if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
331 { 495 {
332 settings->tb_style = xstrdup (sval); 496 settings->tb_style = xstrdup (sval);
333 settings->seen |= SEEN_TB_STYLE; 497 settings->seen |= SEEN_TB_STYLE;
334 } 498 }
335#ifdef HAVE_XFT 499#ifdef HAVE_XFT
500 else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
501 {
502 settings->font = xstrdup (sval);
503 settings->seen |= SEEN_FONT;
504 }
336 else if (strcmp (name, "Xft/Antialias") == 0) 505 else if (strcmp (name, "Xft/Antialias") == 0)
337 { 506 {
338 settings->seen |= SEEN_AA; 507 settings->seen |= SEEN_AA;
@@ -397,6 +566,10 @@ parse_settings (unsigned char *prop,
397 return settings_seen; 566 return settings_seen;
398} 567}
399 568
569/* Read settings from the XSettings property window on display for DPYINFO.
570 Store settings read in SETTINGS.
571 Return non-zero if successful, zero if not. */
572
400static int 573static int
401read_settings (struct x_display_info *dpyinfo, struct xsettings *settings) 574read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
402{ 575{
@@ -426,6 +599,8 @@ read_settings (struct x_display_info *dpyinfo, struct xsettings *settings)
426 return rc != 0; 599 return rc != 0;
427} 600}
428 601
602/* Apply Xft settings in SETTINGS to the Xft library.
603 If SEND_EVENT_P is non-zero store a Lisp event that Xft settings changed. */
429 604
430static void 605static void
431apply_xft_settings (struct x_display_info *dpyinfo, 606apply_xft_settings (struct x_display_info *dpyinfo,
@@ -444,9 +619,9 @@ apply_xft_settings (struct x_display_info *dpyinfo,
444 pat); 619 pat);
445 FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa); 620 FcPatternGetBool (pat, FC_ANTIALIAS, 0, &oldsettings.aa);
446 FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting); 621 FcPatternGetBool (pat, FC_HINTING, 0, &oldsettings.hinting);
447# ifdef FC_HINT_STYLE 622#ifdef FC_HINT_STYLE
448 FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle); 623 FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &oldsettings.hintstyle);
449# endif 624#endif
450 FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter); 625 FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &oldsettings.lcdfilter);
451 FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba); 626 FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba);
452 FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi); 627 FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi);
@@ -485,7 +660,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
485 oldsettings.lcdfilter = settings->lcdfilter; 660 oldsettings.lcdfilter = settings->lcdfilter;
486 } 661 }
487 662
488# ifdef FC_HINT_STYLE 663#ifdef FC_HINT_STYLE
489 if ((settings->seen & SEEN_HINTSTYLE) != 0 664 if ((settings->seen & SEEN_HINTSTYLE) != 0
490 && oldsettings.hintstyle != settings->hintstyle) 665 && oldsettings.hintstyle != settings->hintstyle)
491 { 666 {
@@ -494,7 +669,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
494 ++changed; 669 ++changed;
495 oldsettings.hintstyle = settings->hintstyle; 670 oldsettings.hintstyle = settings->hintstyle;
496 } 671 }
497# endif 672#endif
498 673
499 if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi 674 if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi
500 && settings->dpi > 0) 675 && settings->dpi > 0)
@@ -545,11 +720,13 @@ apply_xft_settings (struct x_display_info *dpyinfo,
545#endif /* HAVE_XFT */ 720#endif /* HAVE_XFT */
546} 721}
547 722
723/* Read XSettings from the display for DPYINFO.
724 If SEND_EVENT_P is non-zero store a Lisp event settings that changed. */
725
548static void 726static void
549read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p) 727read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p)
550{ 728{
551 struct xsettings settings; 729 struct xsettings settings;
552 Lisp_Object dpyname = XCAR (dpyinfo->name_list_element);
553 730
554 if (!read_settings (dpyinfo, &settings)) 731 if (!read_settings (dpyinfo, &settings))
555 return; 732 return;
@@ -557,38 +734,29 @@ read_and_apply_settings (struct x_display_info *dpyinfo, int send_event_p)
557 apply_xft_settings (dpyinfo, True, &settings); 734 apply_xft_settings (dpyinfo, True, &settings);
558 if (settings.seen & SEEN_TB_STYLE) 735 if (settings.seen & SEEN_TB_STYLE)
559 { 736 {
560 Lisp_Object style = Qnil; 737 if (send_event_p)
561 if (strcmp (settings.tb_style, "both") == 0) 738 store_tool_bar_style_changed (settings.tb_style, dpyinfo);
562 style = Qboth; 739 else
563 else if (strcmp (settings.tb_style, "both-horiz") == 0) 740 current_tool_bar_style = map_tool_bar_style (settings.tb_style);
564 style = Qboth_horiz;
565 else if (strcmp (settings.tb_style, "icons") == 0)
566 style = Qimage;
567 else if (strcmp (settings.tb_style, "text") == 0)
568 style = Qtext;
569 if (!NILP (style) && !EQ (style, current_tool_bar_style))
570 {
571 current_tool_bar_style = style;
572 if (send_event_p)
573 store_config_changed_event (Qtool_bar_style, dpyname);
574 }
575 xfree (settings.tb_style); 741 xfree (settings.tb_style);
576 } 742 }
577 743#ifdef HAVE_XFT
578 if (settings.seen & SEEN_FONT) 744 if (settings.seen & SEEN_FONT)
579 { 745 {
580 if (!current_font || strcmp (current_font, settings.font) != 0) 746 if (send_event_p)
747 store_font_name_changed (settings.font);
748 else
581 { 749 {
582 xfree (current_font); 750 xfree (current_font);
583 current_font = settings.font; 751 current_font = xstrdup (settings.font);
584 if (send_event_p)
585 store_config_changed_event (Qfont_name, dpyname);
586 } 752 }
587 else 753 xfree (settings.font);
588 xfree (settings.font);
589 } 754 }
755#endif
590} 756}
591 757
758/* Check if EVENT for the display in DPYINFO is XSettings related. */
759
592void 760void
593xft_settings_event (struct x_display_info *dpyinfo, XEvent *event) 761xft_settings_event (struct x_display_info *dpyinfo, XEvent *event)
594{ 762{
@@ -630,41 +798,130 @@ xft_settings_event (struct x_display_info *dpyinfo, XEvent *event)
630 read_and_apply_settings (dpyinfo, True); 798 read_and_apply_settings (dpyinfo, True);
631} 799}
632 800
801/* Initialize GSettings and read startup values. */
802
803static void
804init_gsettings (void)
805{
806#ifdef HAVE_GSETTINGS
807 GVariant *val;
808 const gchar *const *schemas;
809 int schema_found = 0;
810
811#ifdef HAVE_G_TYPE_INIT
812 g_type_init ();
813#endif
814
815 schemas = g_settings_list_schemas();
816 if (schemas == NULL) return;
817 while (! schema_found && *schemas != NULL)
818 schema_found = strcmp (*schemas++, GSETTINGS_SCHEMA) == 0;
819 if (!schema_found) return;
820
821 gsettings_client = g_settings_new (GSETTINGS_SCHEMA);
822 if (!gsettings_client) return;
823 g_object_ref_sink (G_OBJECT (gsettings_client));
824 g_signal_connect (G_OBJECT (gsettings_client), "changed",
825 G_CALLBACK (something_changed_gsettingsCB), NULL);
826
827 val = g_settings_get_value (gsettings_client, GSETTINGS_TOOL_BAR_STYLE);
828 if (val)
829 {
830 g_variant_ref_sink (val);
831 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
832 current_tool_bar_style
833 = map_tool_bar_style (g_variant_get_string (val, NULL));
834 g_variant_unref (val);
835 }
836
837#ifdef HAVE_XFT
838 val = g_settings_get_value (gsettings_client, GSETTINGS_MONO_FONT);
839 if (val)
840 {
841 g_variant_ref_sink (val);
842 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
843 current_mono_font = xstrdup (g_variant_get_string (val, NULL));
844 g_variant_unref (val);
845 }
846
847 val = g_settings_get_value (gsettings_client, GSETTINGS_FONT_NAME);
848 if (val)
849 {
850 g_variant_ref_sink (val);
851 if (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
852 current_font = xstrdup (g_variant_get_string (val, NULL));
853 g_variant_unref (val);
854 }
855#endif /* HAVE_XFT */
856
857#endif /* HAVE_GSETTINGS */
858}
859
860/* Init GConf and read startup values. */
633 861
634static void 862static void
635init_gconf (void) 863init_gconf (void)
636{ 864{
637#if defined (HAVE_GCONF) && defined (HAVE_XFT) 865#if defined (HAVE_GCONF)
638 char *s; 866 char *s;
639 867
640#ifdef HAVE_G_TYPE_INIT 868#ifdef HAVE_G_TYPE_INIT
641 g_type_init (); 869 g_type_init ();
642#endif 870#endif
871
643 gconf_client = gconf_client_get_default (); 872 gconf_client = gconf_client_get_default ();
644 s = gconf_client_get_string (gconf_client, SYSTEM_MONO_FONT, NULL); 873 gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE);
874 gconf_client_add_dir (gconf_client,
875 GCONF_TOOL_BAR_STYLE,
876 GCONF_CLIENT_PRELOAD_ONELEVEL,
877 NULL);
878 gconf_client_notify_add (gconf_client,
879 GCONF_TOOL_BAR_STYLE,
880 something_changed_gconfCB,
881 NULL, NULL, NULL);
882
883 s = gconf_client_get_string (gconf_client, GCONF_TOOL_BAR_STYLE, NULL);
884 if (s)
885 {
886 current_tool_bar_style = map_tool_bar_style (s);
887 g_free (s);
888 }
889
890#ifdef HAVE_XFT
891 s = gconf_client_get_string (gconf_client, GCONF_MONO_FONT, NULL);
645 if (s) 892 if (s)
646 { 893 {
647 current_mono_font = xstrdup (s); 894 current_mono_font = xstrdup (s);
648 g_free (s); 895 g_free (s);
649 } 896 }
650 s = gconf_client_get_string (gconf_client, SYSTEM_FONT, NULL); 897 s = gconf_client_get_string (gconf_client, GCONF_FONT_NAME, NULL);
651 if (s) 898 if (s)
652 { 899 {
653 current_font = xstrdup (s); 900 current_font = xstrdup (s);
654 g_free (s); 901 g_free (s);
655 } 902 }
656 gconf_client_set_error_handling (gconf_client, GCONF_CLIENT_HANDLE_NONE);
657 gconf_client_add_dir (gconf_client, 903 gconf_client_add_dir (gconf_client,
658 SYSTEM_MONO_FONT, 904 GCONF_MONO_FONT,
905 GCONF_CLIENT_PRELOAD_ONELEVEL,
906 NULL);
907 gconf_client_notify_add (gconf_client,
908 GCONF_MONO_FONT,
909 something_changed_gconfCB,
910 NULL, NULL, NULL);
911 gconf_client_add_dir (gconf_client,
912 GCONF_FONT_NAME,
659 GCONF_CLIENT_PRELOAD_ONELEVEL, 913 GCONF_CLIENT_PRELOAD_ONELEVEL,
660 NULL); 914 NULL);
661 gconf_client_notify_add (gconf_client, 915 gconf_client_notify_add (gconf_client,
662 SYSTEM_MONO_FONT, 916 GCONF_FONT_NAME,
663 something_changedCB, 917 something_changed_gconfCB,
664 NULL, NULL, NULL); 918 NULL, NULL, NULL);
665#endif /* HAVE_GCONF && HAVE_XFT */ 919#endif /* HAVE_XFT */
920#endif /* HAVE_GCONF */
666} 921}
667 922
923/* Init Xsettings and read startup values. */
924
668static void 925static void
669init_xsettings (struct x_display_info *dpyinfo) 926init_xsettings (struct x_display_info *dpyinfo)
670{ 927{
@@ -689,8 +946,12 @@ xsettings_initialize (struct x_display_info *dpyinfo)
689 if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo; 946 if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
690 init_gconf (); 947 init_gconf ();
691 init_xsettings (dpyinfo); 948 init_xsettings (dpyinfo);
949 init_gsettings ();
692} 950}
693 951
952/* Return the system monospaced font.
953 May be NULL if not known. */
954
694const char * 955const char *
695xsettings_get_system_font (void) 956xsettings_get_system_font (void)
696{ 957{
@@ -698,6 +959,9 @@ xsettings_get_system_font (void)
698} 959}
699 960
700#ifdef USE_LUCID 961#ifdef USE_LUCID
962/* Return the system font.
963 May be NULL if not known. */
964
701const char * 965const char *
702xsettings_get_system_normal_font (void) 966xsettings_get_system_normal_font (void)
703{ 967{
@@ -746,6 +1010,9 @@ syms_of_xsettings (void)
746 current_mono_font = NULL; 1010 current_mono_font = NULL;
747 current_font = NULL; 1011 current_font = NULL;
748 first_dpyinfo = NULL; 1012 first_dpyinfo = NULL;
1013#ifdef HAVE_GSETTINGS
1014 gsettings_client = NULL;
1015#endif
749#ifdef HAVE_GCONF 1016#ifdef HAVE_GCONF
750 gconf_client = NULL; 1017 gconf_client = NULL;
751#endif 1018#endif
@@ -769,7 +1036,7 @@ If this variable is nil, Emacs ignores system font changes. */);
769 1036
770#ifdef HAVE_XFT 1037#ifdef HAVE_XFT
771 Fprovide (intern_c_string ("font-render-setting"), Qnil); 1038 Fprovide (intern_c_string ("font-render-setting"), Qnil);
772#ifdef HAVE_GCONF 1039#if defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
773 Fprovide (intern_c_string ("system-font-setting"), Qnil); 1040 Fprovide (intern_c_string ("system-font-setting"), Qnil);
774#endif 1041#endif
775#endif 1042#endif