summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2011-08-06 13:59:36 +0300
committerEli Zaretskii <eliz@gnu.org>2011-08-06 13:59:36 +0300
commitd1410150345acdf2d7693fe00b8169312fe40d14 (patch)
treeaccd9d7c414485e00d9fe30e1d1c28c7e3ea5c60 /src
parentd747b53feb3e403571c724cc5add1e5e354f4408 (diff)
downloademacs-d1410150345acdf2d7693fe00b8169312fe40d14.tar.gz
Fix bug #9254 with crash and cursor positioning under longlines-mode.
src/xdisp.c (set_cursor_from_row): Fix cursor positioning when a display property strides EOL and includes a newline, as in longlines-mode. src/bidi.c (bidi_unshelve_cache): Don't reset the cache if JUST_FREE is non-zero, even if the data buffer is NULL. Fixes a crash in vertical-motion with longlines-mode.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/bidi.c17
-rw-r--r--src/xdisp.c28
3 files changed, 46 insertions, 9 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 60c835cb100..efe542e37d0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2011-08-06 Eli Zaretskii <eliz@gnu.org>
+
+ * xdisp.c (set_cursor_from_row): Fix cursor positioning when a
+ display property strides EOL and includes a newline, as in
+ longlines-mode. (Bug#9254)
+
+ * bidi.c (bidi_unshelve_cache): Don't reset the cache if JUST_FREE
+ is non-zero, even if the data buffer is NULL. Fixes a crash in
+ vertical-motion with longlines-mode. (Bug#9254)
+
2011-08-05 Eli Zaretskii <eliz@gnu.org>
* bidi.c <bidi_cache_total_alloc>: Now static.
diff --git a/src/bidi.c b/src/bidi.c
index 0db144bea6c..2879198ce31 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -666,7 +666,11 @@ bidi_shelve_cache (void)
return databuf;
}
-/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */
+/* Restore the cache state from a copy stashed away by
+ bidi_shelve_cache, and free the buffer used to stash that copy.
+ JUST_FREE non-zero means free the buffer, but don't restore the
+ cache; used when the corresponding iterator is discarded instead of
+ being restored. */
void
bidi_unshelve_cache (void *databuf, int just_free)
{
@@ -674,10 +678,13 @@ bidi_unshelve_cache (void *databuf, int just_free)
if (!p)
{
- /* A NULL pointer means an empty cache. */
- bidi_cache_start = 0;
- bidi_cache_sp = 0;
- bidi_cache_reset ();
+ if (!just_free)
+ {
+ /* A NULL pointer means an empty cache. */
+ bidi_cache_start = 0;
+ bidi_cache_sp = 0;
+ bidi_cache_reset ();
+ }
}
else
{
diff --git a/src/xdisp.c b/src/xdisp.c
index 69baea95b9c..9c281c6736b 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13285,6 +13285,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
/* Last buffer position covered by an overlay string with an integer
`cursor' property. */
EMACS_INT bpos_covered = 0;
+ /* Non-zero means the display string on which to display the cursor
+ comes from a text property, not from an overlay. */
+ int string_from_text_prop = 0;
/* Skip over glyphs not having an object at the start and the end of
the row. These are special glyphs like truncation marks on
@@ -13603,9 +13606,14 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
{
Lisp_Object str;
EMACS_INT tem;
+ /* If the display property covers the newline, we
+ need to search for it one position farther. */
+ EMACS_INT lim = pos_after
+ + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
+ string_from_text_prop = 0;
str = glyph->object;
- tem = string_buffer_position_lim (str, pos, pos_after, 0);
+ tem = string_buffer_position_lim (str, pos, lim, 0);
if (tem == 0 /* from overlay */
|| pos <= tem)
{
@@ -13629,7 +13637,10 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
EMACS_INT strpos = glyph->charpos;
if (tem)
- cursor = glyph;
+ {
+ cursor = glyph;
+ string_from_text_prop = 1;
+ }
for ( ;
(row->reversed_p ? glyph > stop : glyph < stop)
&& EQ (glyph->object, str);
@@ -13730,8 +13741,17 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
/* previous candidate is a glyph from a string that has
a non-nil `cursor' property */
|| (STRINGP (g1->object)
- && !NILP (Fget_char_property (make_number (g1->charpos),
- Qcursor, g1->object)))))
+ && (!NILP (Fget_char_property (make_number (g1->charpos),
+ Qcursor, g1->object))
+ /* pevious candidate is from the same display
+ string as this one, and the display string
+ came from a text property */
+ || (EQ (g1->object, glyph->object)
+ && string_from_text_prop)
+ /* this candidate is from newline and its
+ position is not an exact match */
+ || (INTEGERP (glyph->object)
+ && glyph->charpos != pt_old)))))
return 0;
/* If this candidate gives an exact match, use that. */
if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)